Branch data Line data Source code
1 : : /* Create descriptor for processing file.
2 : : Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
3 : : Copyright (C) 2021, 2022 Mark J. Wielaard <mark@klomp.org>
4 : : This file is part of elfutils.
5 : : Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6 : :
7 : : This file is free software; you can redistribute it and/or modify
8 : : it under the terms of either
9 : :
10 : : * the GNU Lesser General Public License as published by the Free
11 : : Software Foundation; either version 3 of the License, or (at
12 : : your option) any later version
13 : :
14 : : or
15 : :
16 : : * the GNU General Public License as published by the Free
17 : : Software Foundation; either version 2 of the License, or (at
18 : : your option) any later version
19 : :
20 : : or both in parallel, as here.
21 : :
22 : : elfutils is distributed in the hope that it will be useful, but
23 : : WITHOUT ANY WARRANTY; without even the implied warranty of
24 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 : : General Public License for more details.
26 : :
27 : : You should have received copies of the GNU General Public License and
28 : : the GNU Lesser General Public License along with this program. If
29 : : not, see <http://www.gnu.org/licenses/>. */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : # include <config.h>
33 : : #endif
34 : :
35 : : #include <assert.h>
36 : : #include <ctype.h>
37 : : #include <errno.h>
38 : : #include <fcntl.h>
39 : : #include <stdbool.h>
40 : : #include <stddef.h>
41 : : #include <string.h>
42 : : #include <sys/stat.h>
43 : :
44 : : #include "libelfP.h"
45 : : #include "common.h"
46 : :
47 : :
48 : : /* Create descriptor for archive in memory. */
49 : : static inline Elf *
50 : 157 : file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
51 : : Elf_Cmd cmd, Elf *parent)
52 : : {
53 : 157 : Elf *elf;
54 : :
55 : : /* Create a descriptor. */
56 : 157 : elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
57 : : ELF_K_AR, 0);
58 [ + - ]: 157 : if (elf != NULL)
59 : : {
60 : : /* We don't read all the symbol tables in advance. All this will
61 : : happen on demand. */
62 : 157 : elf->state.ar.offset = offset + SARMAG;
63 : :
64 : 157 : elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
65 : : }
66 : :
67 : 157 : return elf;
68 : : }
69 : :
70 : :
71 : : static size_t
72 : 15631 : get_shnum (void *map_address, unsigned char *e_ident, int fildes,
73 : : int64_t offset, size_t maxsize)
74 : : {
75 : 15631 : size_t result;
76 : 15631 : union
77 : : {
78 : : Elf32_Ehdr *e32;
79 : : Elf64_Ehdr *e64;
80 : : void *p;
81 : : } ehdr;
82 : 15631 : union
83 : : {
84 : : Elf32_Ehdr e32;
85 : : Elf64_Ehdr e64;
86 : : } ehdr_mem;
87 : 15631 : bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
88 : :
89 [ + - ]: 15631 : if ((is32 && maxsize < sizeof (Elf32_Ehdr))
90 [ - + ]: 15631 : || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
91 : : {
92 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
93 : 0 : return (size_t) -1l;
94 : : }
95 : :
96 : : /* Make the ELF header available. */
97 [ + + ]: 15631 : if (e_ident[EI_DATA] == MY_ELFDATA
98 : : && (ALLOW_UNALIGNED
99 : : || (((size_t) e_ident
100 : : & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
101 : : - 1)) == 0)))
102 : : ehdr.p = e_ident;
103 : : else
104 : : {
105 : : /* We already read the ELF header. We have to copy the header
106 : : since we possibly modify the data here and the caller
107 : : expects the memory it passes in to be preserved. */
108 : 855 : ehdr.p = &ehdr_mem;
109 : :
110 [ + + ]: 855 : if (is32)
111 : : {
112 : 397 : if (ALLOW_UNALIGNED)
113 : : {
114 : 397 : ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
115 : 397 : ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
116 : : }
117 : : else
118 : : memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
119 : :
120 : 397 : if (e_ident[EI_DATA] != MY_ELFDATA)
121 : : {
122 : 397 : CONVERT (ehdr_mem.e32.e_shnum);
123 : 397 : CONVERT (ehdr_mem.e32.e_shoff);
124 : : }
125 : : }
126 : : else
127 : : {
128 : 458 : if (ALLOW_UNALIGNED)
129 : : {
130 : 458 : ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
131 : 458 : ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
132 : : }
133 : : else
134 : : memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
135 : :
136 : 458 : if (e_ident[EI_DATA] != MY_ELFDATA)
137 : : {
138 : 458 : CONVERT (ehdr_mem.e64.e_shnum);
139 : 458 : CONVERT (ehdr_mem.e64.e_shoff);
140 : : }
141 : : }
142 : : }
143 : :
144 [ + + ]: 15631 : if (is32)
145 : : {
146 : : /* Get the number of sections from the ELF header. */
147 : 1113 : result = ehdr.e32->e_shnum;
148 : :
149 [ + + + + ]: 1113 : if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
150 : : {
151 [ + - ]: 52 : if (unlikely (ehdr.e32->e_shoff >= maxsize)
152 [ + - ]: 52 : || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
153 : : /* Cannot read the first section header. */
154 : : return 0;
155 : :
156 [ + + ]: 52 : if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
157 [ + + ]: 40 : && (ALLOW_UNALIGNED
158 : : || (((size_t) ((char *) (map_address + ehdr.e32->e_shoff
159 : : + offset)))
160 : : & (__alignof__ (Elf32_Shdr) - 1)) == 0))
161 : : /* We can directly access the memory. */
162 : 24 : result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
163 : 24 : + offset))->sh_size;
164 : : else
165 : : {
166 : 28 : Elf32_Word size;
167 : 28 : ssize_t r;
168 : :
169 [ + + ]: 28 : if (likely (map_address != NULL))
170 : : /* gcc will optimize the memcpy to a simple memory
171 : : access while taking care of alignment issues. */
172 : 44 : memcpy (&size, ((char *) map_address
173 : : + ehdr.e32->e_shoff
174 : 16 : + offset
175 : 16 : + offsetof (Elf32_Shdr, sh_size)),
176 : : sizeof (Elf32_Word));
177 : : else
178 [ - + ]: 12 : if (unlikely ((r = pread_retry (fildes, &size,
179 : : sizeof (Elf32_Word),
180 : : offset + ehdr.e32->e_shoff
181 : : + offsetof (Elf32_Shdr,
182 : : sh_size)))
183 : : != sizeof (Elf32_Word)))
184 : : {
185 [ # # ]: 0 : if (r < 0)
186 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
187 : : else
188 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
189 : 0 : return (size_t) -1l;
190 : : }
191 : :
192 [ + + ]: 28 : if (e_ident[EI_DATA] != MY_ELFDATA)
193 : 20 : CONVERT (size);
194 : :
195 : 28 : result = size;
196 : : }
197 : : }
198 : :
199 : : /* If the section headers were truncated, pretend none were there. */
200 [ + - ]: 1113 : if (ehdr.e32->e_shoff > maxsize
201 [ - + ]: 1113 : || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
202 : 0 : result = 0;
203 : : }
204 : : else
205 : : {
206 : : /* Get the number of sections from the ELF header. */
207 : 14518 : result = ehdr.e64->e_shnum;
208 : :
209 [ + + + + ]: 14518 : if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
210 : : {
211 [ + - ]: 41 : if (unlikely (ehdr.e64->e_shoff >= maxsize)
212 [ + - ]: 41 : || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
213 : : /* Cannot read the first section header. */
214 : 0 : return 0;
215 : :
216 : 41 : Elf64_Xword size;
217 [ + + ]: 41 : if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
218 [ + + ]: 33 : && (ALLOW_UNALIGNED
219 : : || (((size_t) ((char *) (map_address + ehdr.e64->e_shoff
220 : : + offset)))
221 : : & (__alignof__ (Elf64_Shdr) - 1)) == 0))
222 : : /* We can directly access the memory. */
223 : 17 : size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
224 : 17 : + offset))->sh_size;
225 : : else
226 : : {
227 : 24 : ssize_t r;
228 [ + + ]: 24 : if (likely (map_address != NULL))
229 : : /* gcc will optimize the memcpy to a simple memory
230 : : access while taking care of alignment issues. */
231 : 40 : memcpy (&size, ((char *) map_address
232 : : + ehdr.e64->e_shoff
233 : 16 : + offset
234 : 16 : + offsetof (Elf64_Shdr, sh_size)),
235 : : sizeof (Elf64_Xword));
236 : : else
237 [ - + ]: 8 : if (unlikely ((r = pread_retry (fildes, &size,
238 : : sizeof (Elf64_Xword),
239 : : offset + ehdr.e64->e_shoff
240 : : + offsetof (Elf64_Shdr,
241 : : sh_size)))
242 : : != sizeof (Elf64_Xword)))
243 : : {
244 [ # # ]: 0 : if (r < 0)
245 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
246 : : else
247 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
248 : 0 : return (size_t) -1l;
249 : : }
250 : :
251 [ + + ]: 24 : if (e_ident[EI_DATA] != MY_ELFDATA)
252 : 20 : CONVERT (size);
253 : : }
254 : :
255 : : /* Although sh_size is an Elf64_Xword and can contain a 64bit
256 : : value, we only expect an 32bit value max. GElf_Word is
257 : : 32bit unsigned. */
258 [ - + ]: 41 : if (size > ~((GElf_Word) 0))
259 : : {
260 : : /* Invalid value, it is too large. */
261 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
262 : 0 : return (size_t) -1l;
263 : : }
264 : :
265 : 41 : result = size;
266 : : }
267 : :
268 : : /* If the section headers were truncated, pretend none were there. */
269 [ + + ]: 14518 : if (ehdr.e64->e_shoff > maxsize
270 [ - + ]: 14515 : || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
271 : 3 : result = 0;
272 : : }
273 : :
274 : : return result;
275 : : }
276 : :
277 : :
278 : : /* Create descriptor for ELF file in memory. */
279 : : static Elf *
280 : 15631 : file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
281 : : int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
282 : : {
283 : : /* Verify the binary is of the class we can handle. */
284 [ + - - + ]: 15631 : if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
285 : : && e_ident[EI_CLASS] != ELFCLASS64)
286 : : /* We also can only handle two encodings. */
287 : : || (e_ident[EI_DATA] != ELFDATA2LSB
288 : : && e_ident[EI_DATA] != ELFDATA2MSB)))
289 : : {
290 : : /* Cannot handle this. */
291 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
292 : 0 : return NULL;
293 : : }
294 : :
295 : : /* Determine the number of sections. Returns -1 and sets libelf errno
296 : : if the file handle or elf file is invalid. Returns zero if there
297 : : are no section headers (or they cannot be read). */
298 : 15631 : size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
299 [ + - ]: 15631 : if (scncnt == (size_t) -1l)
300 : : /* Could not determine the number of sections. */
301 : : return NULL;
302 : :
303 : : /* Check for too many sections. */
304 [ + + ]: 15631 : if (e_ident[EI_CLASS] == ELFCLASS32)
305 : : {
306 [ - + ]: 1113 : if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
307 : : {
308 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
309 : 0 : return NULL;
310 : : }
311 : : }
312 [ - + ]: 14518 : else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
313 : : {
314 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
315 : 0 : return NULL;
316 : : }
317 : :
318 : : /* We can now allocate the memory. Even if there are no section headers,
319 : : we allocate space for a zeroth section in case we need it later. */
320 [ + + ]: 15631 : const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
321 : 190 : ? 1 : 0);
322 : 15631 : Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
323 : : ELF_K_ELF, scnmax * sizeof (Elf_Scn));
324 [ + - ]: 15631 : if (elf == NULL)
325 : : /* Not enough memory. allocate_elf will have set libelf errno. */
326 : : return NULL;
327 : :
328 [ - + ]: 15631 : assert ((unsigned int) scncnt == scncnt);
329 : 15631 : assert (offsetof (struct Elf, state.elf32.scns)
330 : : == offsetof (struct Elf, state.elf64.scns));
331 : 15631 : elf->state.elf32.scns.cnt = scncnt;
332 : 15631 : elf->state.elf32.scns.max = scnmax;
333 : :
334 : : /* Some more or less arbitrary value. */
335 : 15631 : elf->state.elf.scnincr = 10;
336 : :
337 : : /* Make the class easily available. */
338 : 15631 : elf->class = e_ident[EI_CLASS];
339 : :
340 [ + + ]: 15631 : if (e_ident[EI_CLASS] == ELFCLASS32)
341 : : {
342 : : /* This pointer might not be directly usable if the alignment is
343 : : not sufficient for the architecture. */
344 : 1113 : Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
345 : :
346 : : /* This is a 32-bit binary. */
347 [ + + ]: 1113 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
348 [ + + ]: 667 : && (ALLOW_UNALIGNED
349 : : || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
350 : : {
351 : : /* We can use the mmapped memory. */
352 : 437 : elf->state.elf32.ehdr = ehdr;
353 : : }
354 : : else
355 : : {
356 : : /* Copy the ELF header. */
357 [ + + ]: 676 : elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
358 : : sizeof (Elf32_Ehdr));
359 : :
360 [ + + ]: 676 : if (e_ident[EI_DATA] != MY_ELFDATA)
361 : : {
362 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_type);
363 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_machine);
364 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_version);
365 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_entry);
366 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
367 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
368 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_flags);
369 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
370 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
371 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
372 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
373 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
374 : 397 : CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
375 : : }
376 : : }
377 : :
378 : : /* Don't precache the phdr pointer here.
379 : : elf32_getphdr will validate it against the size when asked. */
380 : :
381 : 1113 : Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
382 [ + + + + ]: 1113 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
383 : : && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */
384 [ + + ]: 437 : && (ALLOW_UNALIGNED
385 : : || ((((uintptr_t) ehdr + e_shoff)
386 : : & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
387 : : {
388 [ + + - + ]: 254 : if (unlikely (scncnt > 0 && e_shoff >= maxsize)
389 [ - + ]: 254 : || unlikely (maxsize - e_shoff
390 : : < scncnt * sizeof (Elf32_Shdr)))
391 : : {
392 : 0 : free_and_out:
393 : 0 : free (elf);
394 : 0 : __libelf_seterrno (ELF_E_INVALID_ELF);
395 : 0 : return NULL;
396 : : }
397 : :
398 [ + + ]: 254 : if (scncnt > 0)
399 : 243 : elf->state.elf32.shdr
400 : 243 : = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
401 : :
402 [ + + ]: 596654 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
403 : : {
404 : 596400 : elf->state.elf32.scns.data[cnt].index = cnt;
405 : 596400 : elf->state.elf32.scns.data[cnt].elf = elf;
406 : 596400 : elf->state.elf32.scns.data[cnt].shdr.e32 =
407 : 596400 : &elf->state.elf32.shdr[cnt];
408 [ + + ]: 596400 : if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
409 [ + + ]: 596398 : && likely (elf->state.elf32.shdr[cnt].sh_size
410 : : <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
411 : 596391 : elf->state.elf32.scns.data[cnt].rawdata_base =
412 : 596391 : elf->state.elf32.scns.data[cnt].data_base =
413 : : ((char *) map_address + offset
414 : 596391 : + elf->state.elf32.shdr[cnt].sh_offset);
415 : 596400 : elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
416 : :
417 : : /* If this is a section with an extended index add a
418 : : reference in the section which uses the extended
419 : : index. */
420 [ - + ]: 596400 : if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
421 [ # # ]: 0 : && elf->state.elf32.shdr[cnt].sh_link < scncnt)
422 : 0 : elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
423 : 0 : = cnt;
424 : :
425 : : /* Set the own shndx_index field in case it has not yet
426 : : been set. */
427 [ + - ]: 596400 : if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
428 : 596400 : elf->state.elf32.scns.data[cnt].shndx_index = -1;
429 : : }
430 : : }
431 : : else
432 : : {
433 [ + + ]: 3231776 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
434 : : {
435 : 3230917 : elf->state.elf32.scns.data[cnt].index = cnt;
436 : 3230917 : elf->state.elf32.scns.data[cnt].elf = elf;
437 : 3230917 : elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
438 : : }
439 : : }
440 : :
441 : : /* So far only one block with sections. */
442 : 1113 : elf->state.elf32.scns_last = &elf->state.elf32.scns;
443 : : }
444 : : else
445 : : {
446 : : /* This pointer might not be directly usable if the alignment is
447 : : not sufficient for the architecture. */
448 : 14518 : Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
449 : :
450 : : /* This is a 64-bit binary. */
451 [ + + ]: 14518 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
452 [ + + ]: 6818 : && (ALLOW_UNALIGNED
453 : : || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
454 : : {
455 : : /* We can use the mmapped memory. */
456 : 6539 : elf->state.elf64.ehdr = ehdr;
457 : : }
458 : : else
459 : : {
460 : : /* Copy the ELF header. */
461 [ + + ]: 7979 : elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
462 : : sizeof (Elf64_Ehdr));
463 : :
464 [ + + ]: 7979 : if (e_ident[EI_DATA] != MY_ELFDATA)
465 : : {
466 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_type);
467 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_machine);
468 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_version);
469 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_entry);
470 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
471 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
472 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_flags);
473 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
474 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
475 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
476 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
477 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
478 : 458 : CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
479 : : }
480 : : }
481 : :
482 : : /* Don't precache the phdr pointer here.
483 : : elf64_getphdr will validate it against the size when asked. */
484 : :
485 : 14518 : Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
486 [ + + + + ]: 14518 : if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
487 : : && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write. */
488 [ + + ]: 6539 : && (ALLOW_UNALIGNED
489 : : || ((((uintptr_t) ehdr + e_shoff)
490 : : & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
491 : : {
492 [ + - ]: 5886 : if (unlikely (scncnt > 0 && e_shoff >= maxsize)
493 [ - + ]: 5886 : || unlikely (maxsize - e_shoff
494 : : < scncnt * sizeof (Elf64_Shdr)))
495 : 0 : goto free_and_out;
496 : :
497 [ + + ]: 5886 : if (scncnt > 0)
498 : 5858 : elf->state.elf64.shdr
499 : 5858 : = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
500 : :
501 [ + + ]: 820959 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
502 : : {
503 : 815073 : elf->state.elf64.scns.data[cnt].index = cnt;
504 : 815073 : elf->state.elf64.scns.data[cnt].elf = elf;
505 : 815073 : elf->state.elf64.scns.data[cnt].shdr.e64 =
506 : 815073 : &elf->state.elf64.shdr[cnt];
507 [ + + ]: 815073 : if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
508 [ + + ]: 814931 : && likely (elf->state.elf64.shdr[cnt].sh_size
509 : : <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
510 : 814880 : elf->state.elf64.scns.data[cnt].rawdata_base =
511 : 814880 : elf->state.elf64.scns.data[cnt].data_base =
512 : : ((char *) map_address + offset
513 : 814880 : + elf->state.elf64.shdr[cnt].sh_offset);
514 : 815073 : elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
515 : :
516 : : /* If this is a section with an extended index add a
517 : : reference in the section which uses the extended
518 : : index. */
519 [ - + ]: 815073 : if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
520 [ # # ]: 0 : && elf->state.elf64.shdr[cnt].sh_link < scncnt)
521 : 0 : elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
522 : 0 : = cnt;
523 : :
524 : : /* Set the own shndx_index field in case it has not yet
525 : : been set. */
526 [ + - ]: 815073 : if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
527 : 815073 : elf->state.elf64.scns.data[cnt].shndx_index = -1;
528 : : }
529 : : }
530 : : else
531 : : {
532 [ + + ]: 2786113 : for (size_t cnt = 0; cnt < scncnt; ++cnt)
533 : : {
534 : 2777481 : elf->state.elf64.scns.data[cnt].index = cnt;
535 : 2777481 : elf->state.elf64.scns.data[cnt].elf = elf;
536 : 2777481 : elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
537 : : }
538 : : }
539 : :
540 : : /* So far only one block with sections. */
541 : 14518 : elf->state.elf64.scns_last = &elf->state.elf64.scns;
542 : : }
543 : :
544 : : return elf;
545 : : }
546 : :
547 : :
548 : : Elf *
549 : : internal_function
550 : 7863 : __libelf_read_mmaped_file (int fildes, void *map_address, int64_t offset,
551 : : size_t maxsize, Elf_Cmd cmd, Elf *parent)
552 : : {
553 : : /* We have to find out what kind of file this is. We handle ELF
554 : : files and archives. To find out what we have we must look at the
555 : : header. The header for an ELF file is EI_NIDENT bytes in size,
556 : : the header for an archive file SARMAG bytes long. */
557 : 7863 : unsigned char *e_ident = (unsigned char *) map_address + offset;
558 : :
559 : : /* See what kind of object we have here. */
560 : 7863 : Elf_Kind kind = determine_kind (e_ident, maxsize);
561 : :
562 [ + + + ]: 7863 : switch (kind)
563 : : {
564 : 7485 : case ELF_K_ELF:
565 : 7485 : return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
566 : : cmd, parent);
567 : :
568 : 30 : case ELF_K_AR:
569 : 30 : return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
570 : :
571 : : default:
572 : 348 : break;
573 : : }
574 : :
575 : : /* This case is easy. Since we cannot do anything with this file
576 : : create a dummy descriptor. */
577 : 348 : return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
578 : : ELF_K_NONE, 0);
579 : : }
580 : :
581 : :
582 : : static Elf *
583 : 8510 : read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
584 : : Elf *parent)
585 : : {
586 : : /* We have to find out what kind of file this is. We handle ELF
587 : : files and archives. To find out what we have we must read the
588 : : header. The identification header for an ELF file is EI_NIDENT
589 : : bytes in size, but we read the whole ELF header since we will
590 : : need it anyway later. For archives the header in SARMAG bytes
591 : : long. Read the maximum of these numbers.
592 : :
593 : : XXX We have to change this for the extended `ar' format some day.
594 : :
595 : : Use a union to ensure alignment. We might later access the
596 : : memory as a ElfXX_Ehdr. */
597 : 8510 : union
598 : : {
599 : : Elf64_Ehdr ehdr;
600 : : unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
601 : : } mem;
602 : :
603 : : /* Read the head of the file. */
604 : 17020 : ssize_t nread = pread_retry (fildes, mem.header,
605 : 8510 : MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
606 : : maxsize),
607 : : offset);
608 [ - + ]: 8510 : if (unlikely (nread == -1))
609 : : {
610 : : /* We cannot even read the head of the file. Maybe FILDES is associated
611 : : with an unseekable device. This is nothing we can handle. */
612 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
613 : 0 : return NULL;
614 : : }
615 : :
616 : : /* See what kind of object we have here. */
617 : 8510 : Elf_Kind kind = determine_kind (mem.header, nread);
618 : :
619 [ + + + ]: 8510 : switch (kind)
620 : : {
621 : 127 : case ELF_K_AR:
622 : 127 : return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
623 : :
624 : 8146 : case ELF_K_ELF:
625 : : /* Make sure at least the ELF header is contained in the file. */
626 [ + - ]: 8146 : if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
627 [ + + ]: 8146 : ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
628 : 8146 : return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
629 : : parent);
630 : 237 : FALLTHROUGH;
631 : :
632 : : default:
633 : 237 : break;
634 : : }
635 : :
636 : : /* This case is easy. Since we cannot do anything with this file
637 : : create a dummy descriptor. */
638 : 237 : return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
639 : : ELF_K_NONE, 0);
640 : : }
641 : :
642 : :
643 : : /* Open a file for reading. If possible we will try to mmap() the file. */
644 : : static struct Elf *
645 : 16274 : read_file (int fildes, int64_t offset, size_t maxsize,
646 : : Elf_Cmd cmd, Elf *parent)
647 : : {
648 : 16274 : void *map_address = NULL;
649 : 16274 : int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
650 : : || cmd == ELF_C_WRITE_MMAP
651 : 16274 : || cmd == ELF_C_READ_MMAP_PRIVATE);
652 : :
653 [ + + ]: 16274 : if (parent == NULL)
654 : : {
655 [ + - ]: 9010 : if (maxsize == ~((size_t) 0))
656 : : {
657 : : /* We don't know in the moment how large the file is.
658 : : Determine it now. */
659 : 9010 : struct stat st;
660 : :
661 [ + - ]: 9010 : if (fstat (fildes, &st) == 0
662 : : && (sizeof (size_t) >= sizeof (st.st_size)
663 : : || st.st_size <= ~((size_t) 0)))
664 : 9010 : maxsize = (size_t) st.st_size;
665 : : }
666 : : }
667 : : else
668 : : {
669 : : /* The parent is already loaded. Use it. */
670 [ - + ]: 7264 : assert (maxsize != ~((size_t) 0));
671 : : }
672 : :
673 [ + + ]: 16274 : if (use_mmap)
674 : : {
675 [ + + ]: 7775 : if (parent == NULL)
676 : : {
677 : : /* We try to map the file ourself. */
678 [ + + ]: 14262 : map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
679 : : ? PROT_READ
680 : : : PROT_READ|PROT_WRITE),
681 : 7679 : cmd == ELF_C_READ_MMAP_PRIVATE
682 [ + + ]: 7679 : || cmd == ELF_C_READ_MMAP
683 : : ? MAP_PRIVATE : MAP_SHARED,
684 : : fildes, offset);
685 : :
686 [ + + ]: 7679 : if (map_address == MAP_FAILED)
687 : : map_address = NULL;
688 : : }
689 : : else
690 : : {
691 : 96 : map_address = parent->map_address;
692 : : }
693 : : }
694 : :
695 : : /* If we have the file in memory optimize the access. */
696 [ + - ]: 7764 : if (map_address != NULL)
697 : : {
698 [ - + ]: 7764 : assert (map_address != MAP_FAILED);
699 : :
700 : 7764 : struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
701 : : offset, maxsize, cmd,
702 : : parent);
703 : :
704 : : /* If something went wrong during the initialization unmap the
705 : : memory if we mmaped here. */
706 [ - + ]: 7764 : if (result == NULL
707 [ # # ]: 0 : && (parent == NULL
708 [ # # ]: 0 : || parent->map_address != map_address))
709 : 0 : munmap (map_address, maxsize);
710 [ + + ]: 7764 : else if (parent == NULL)
711 : : /* Remember that we mmap()ed the memory. */
712 : 7668 : result->flags |= ELF_F_MMAPPED;
713 : :
714 : 7764 : return result;
715 : : }
716 : :
717 : : /* Otherwise we have to do it the hard way. We read as much as necessary
718 : : from the file whenever we need information which is not available. */
719 : 8510 : return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
720 : : }
721 : :
722 : :
723 : : /* Find the entry with the long names for the content of this archive. */
724 : : static const char *
725 : 102 : read_long_names (Elf *elf)
726 : : {
727 : 102 : off_t offset = SARMAG; /* This is the first entry. */
728 : 204 : struct ar_hdr hdrm;
729 : 204 : struct ar_hdr *hdr;
730 : 204 : char *newp;
731 : 204 : size_t len;
732 : :
733 : 306 : while (1)
734 : 102 : {
735 [ - + ]: 204 : if (elf->map_address != NULL)
736 : : {
737 [ # # ]: 0 : if ((size_t) offset > elf->maximum_size
738 [ # # ]: 0 : || elf->maximum_size - offset < sizeof (struct ar_hdr))
739 : 0 : return NULL;
740 : :
741 : : /* The data is mapped. */
742 : 0 : hdr = (struct ar_hdr *) (elf->map_address + offset);
743 : : }
744 : : else
745 : : {
746 : : /* Read the header from the file. */
747 [ + - ]: 204 : if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
748 : : elf->start_offset + offset)
749 : : != sizeof (hdrm)))
750 : : return NULL;
751 : :
752 : : hdr = &hdrm;
753 : : }
754 : :
755 : : /* The ar_size is given as a fixed size decimal string, right
756 : : padded with spaces. Make sure we read it properly even if
757 : : there is no terminating space. */
758 : 204 : char buf[sizeof (hdr->ar_size) + 1];
759 : 204 : const char *string = hdr->ar_size;
760 [ - + ]: 204 : if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
761 : : {
762 : 0 : *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
763 : 0 : string = buf;
764 : : }
765 : :
766 : : /* atol expects to see at least one digit.
767 : : It also cannot be negative (-). */
768 [ + - ]: 204 : if (!isdigit(string[0]))
769 : : return NULL;
770 : 204 : len = atol (string);
771 : :
772 [ + + ]: 204 : if (memcmp (hdr->ar_name, "// ", 16) == 0)
773 : : break;
774 : :
775 : 102 : offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
776 : : }
777 : :
778 : : /* Sanity check len early if we can. */
779 [ - + ]: 102 : if (elf->map_address != NULL)
780 : : {
781 [ # # ]: 0 : if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
782 : : return NULL;
783 : : }
784 : :
785 : : /* Due to the stupid format of the long name table entry (which are not
786 : : NUL terminted) we have to provide an appropriate representation anyhow.
787 : : Therefore we always make a copy which has the appropriate form. */
788 : 102 : newp = malloc (len);
789 [ + - ]: 102 : if (newp != NULL)
790 : : {
791 : 102 : char *runp;
792 : :
793 [ - + ]: 102 : if (elf->map_address != NULL)
794 : : {
795 : : /* Simply copy it over. */
796 : 0 : elf->state.ar.long_names = (char *) memcpy (newp,
797 : : elf->map_address + offset
798 : 0 : + sizeof (struct ar_hdr),
799 : : len);
800 : : }
801 : : else
802 : : {
803 [ - + ]: 102 : if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
804 : : elf->start_offset + offset
805 : : + sizeof (struct ar_hdr))
806 : : != len))
807 : : {
808 : : /* We were not able to read all data. */
809 : 0 : free (newp);
810 : 0 : elf->state.ar.long_names = NULL;
811 : 0 : return NULL;
812 : : }
813 : 102 : elf->state.ar.long_names = newp;
814 : : }
815 : :
816 : 102 : elf->state.ar.long_names_len = len;
817 : :
818 : : /* Now NUL-terminate the strings. */
819 : 102 : runp = newp;
820 : 4182 : while (1)
821 : : {
822 : 4182 : char *startp = runp;
823 : 4182 : runp = (char *) memchr (runp, '/', newp + len - runp);
824 [ + + ]: 4182 : if (runp == NULL)
825 : : {
826 : : /* This was the last entry. Clear any left overs. */
827 : 102 : memset (startp, '\0', newp + len - startp);
828 : : break;
829 : : }
830 : :
831 : : /* NUL-terminate the string. */
832 : 4080 : *runp++ = '\0';
833 : :
834 : : /* A sanity check. Somebody might have generated invalid
835 : : archive. */
836 [ + - ]: 4080 : if (runp >= newp + len)
837 : : break;
838 : : }
839 : : }
840 : :
841 : : return newp;
842 : : }
843 : :
844 : :
845 : : /* Read the next archive header. */
846 : : int
847 : : internal_function
848 : 7284 : __libelf_next_arhdr_wrlock (Elf *elf)
849 : : {
850 : 7284 : struct ar_hdr *ar_hdr;
851 : 7284 : Elf_Arhdr *elf_ar_hdr;
852 : :
853 [ + + ]: 7284 : if (elf->map_address != NULL)
854 : : {
855 : : /* See whether this entry is in the file. */
856 [ + - + + ]: 116 : if (unlikely ((size_t) elf->state.ar.offset
857 : : > elf->start_offset + elf->maximum_size
858 : : || (elf->start_offset + elf->maximum_size
859 : : - elf->state.ar.offset) < sizeof (struct ar_hdr)))
860 : : {
861 : : /* This record is not anymore in the file. */
862 : 20 : __libelf_seterrno (ELF_E_RANGE);
863 : 20 : return -1;
864 : : }
865 : 96 : ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
866 : : }
867 : : else
868 : : {
869 : 7168 : ar_hdr = &elf->state.ar.ar_hdr;
870 : :
871 [ - + ]: 7168 : if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
872 : : elf->state.ar.offset)
873 : : != sizeof (struct ar_hdr)))
874 : : {
875 : : /* Something went wrong while reading the file. */
876 : 0 : __libelf_seterrno (ELF_E_RANGE);
877 : 0 : return -1;
878 : : }
879 : : }
880 : :
881 : : /* One little consistency check. */
882 [ - + ]: 7264 : if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
883 : : {
884 : : /* This is no valid archive. */
885 : 0 : __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
886 : 0 : return -1;
887 : : }
888 : :
889 : : /* Copy the raw name over to a NUL terminated buffer. */
890 [ + + ]: 7264 : *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
891 : :
892 : 7264 : elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
893 : :
894 : : /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
895 : : Determine whether this is a special entry. */
896 [ + + ]: 7264 : if (ar_hdr->ar_name[0] == '/')
897 : : {
898 [ + + ]: 2078 : if (ar_hdr->ar_name[1] == ' '
899 [ + - ]: 120 : && memcmp (ar_hdr->ar_name, "/ ", 16) == 0)
900 : : /* This is the index. */
901 : 120 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
902 [ + + ]: 1958 : else if (ar_hdr->ar_name[1] == 'S'
903 [ + - ]: 2 : && memcmp (ar_hdr->ar_name, "/SYM64/ ", 16) == 0)
904 : : /* 64-bit index. */
905 : 2 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
906 [ + + ]: 1956 : else if (ar_hdr->ar_name[1] == '/'
907 [ + - ]: 116 : && memcmp (ar_hdr->ar_name, "// ", 16) == 0)
908 : : /* This is the array with the long names. */
909 : 116 : elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
910 [ + - ]: 1840 : else if (likely (isdigit (ar_hdr->ar_name[1])))
911 : : {
912 : 1840 : size_t offset;
913 : :
914 : : /* This is a long name. First we have to read the long name
915 : : table, if this hasn't happened already. */
916 [ + + - + ]: 1840 : if (unlikely (elf->state.ar.long_names == NULL
917 : : && read_long_names (elf) == NULL))
918 : : {
919 : : /* No long name table although it is reference. The archive is
920 : : broken. */
921 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
922 : 0 : return -1;
923 : : }
924 : :
925 : 1840 : offset = atol (ar_hdr->ar_name + 1);
926 [ - + ]: 1840 : if (unlikely (offset >= elf->state.ar.long_names_len))
927 : : {
928 : : /* The index in the long name table is larger than the table. */
929 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
930 : 0 : return -1;
931 : : }
932 : 1840 : elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
933 : : }
934 : : else
935 : : {
936 : : /* This is none of the known special entries. */
937 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
938 : 0 : return -1;
939 : : }
940 : : }
941 : : else
942 : : {
943 : 5186 : char *endp;
944 : :
945 : : /* It is a normal entry. Copy over the name. */
946 : 5186 : endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
947 : : '/', 16);
948 [ + - ]: 5186 : if (endp != NULL)
949 : 5186 : endp[-1] = '\0';
950 : : else
951 : : {
952 : : /* In the old BSD style of archive, there is no / terminator.
953 : : Instead, there is space padding at the end of the name. */
954 : : size_t i = 15;
955 : 0 : do
956 : 0 : elf->state.ar.ar_name[i] = '\0';
957 [ # # # # ]: 0 : while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
958 : : }
959 : :
960 : 5186 : elf_ar_hdr->ar_name = elf->state.ar.ar_name;
961 : : }
962 : :
963 [ - + ]: 7264 : if (unlikely (ar_hdr->ar_size[0] == ' '))
964 : : /* Something is really wrong. We cannot live without a size for
965 : : the member since it will not be possible to find the next
966 : : archive member. */
967 : : {
968 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
969 : 0 : return -1;
970 : : }
971 : :
972 : : /* Since there are no specialized functions to convert ASCII to
973 : : time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
974 : : atoll depending on the size of the types. We are also prepared
975 : : for the case where the whole field in the `struct ar_hdr' is
976 : : filled in which case we cannot simply use atol/l but instead have
977 : : to create a temporary copy. Note that all fields use decimal
978 : : encoding, except ar_mode which uses octal. */
979 : :
980 : : #define INT_FIELD(FIELD) \
981 : : do \
982 : : { \
983 : : char buf[sizeof (ar_hdr->FIELD) + 1]; \
984 : : const char *string = ar_hdr->FIELD; \
985 : : if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \
986 : : { \
987 : : *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \
988 : : = '\0'; \
989 : : string = buf; \
990 : : } \
991 : : if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \
992 : : elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string); \
993 : : else \
994 : : elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string); \
995 : : } \
996 : : while (0)
997 : :
998 : : #define OCT_FIELD(FIELD) \
999 : : do \
1000 : : { \
1001 : : char buf[sizeof (ar_hdr->FIELD) + 1]; \
1002 : : const char *string = ar_hdr->FIELD; \
1003 : : if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \
1004 : : { \
1005 : : *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \
1006 : : = '\0'; \
1007 : : string = buf; \
1008 : : } \
1009 : : if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \
1010 : : elf_ar_hdr->FIELD \
1011 : : = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8); \
1012 : : else \
1013 : : elf_ar_hdr->FIELD \
1014 : : = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8); \
1015 : : } \
1016 : : while (0)
1017 : :
1018 [ - + ]: 7264 : INT_FIELD (ar_date);
1019 [ - + ]: 7264 : INT_FIELD (ar_uid);
1020 [ - + ]: 7264 : INT_FIELD (ar_gid);
1021 [ - + ]: 7264 : OCT_FIELD (ar_mode);
1022 [ - + ]: 7264 : INT_FIELD (ar_size);
1023 : :
1024 [ - + ]: 7264 : if (elf_ar_hdr->ar_size < 0)
1025 : : {
1026 : 0 : __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
1027 : 0 : return -1;
1028 : : }
1029 : :
1030 : : /* Truncated file? */
1031 : 7264 : size_t maxsize;
1032 : 7264 : maxsize = (elf->start_offset + elf->maximum_size
1033 : 7264 : - elf->state.ar.offset - sizeof (struct ar_hdr));
1034 [ - + ]: 7264 : if ((size_t) elf_ar_hdr->ar_size > maxsize)
1035 : 0 : elf_ar_hdr->ar_size = maxsize;
1036 : :
1037 : : return 0;
1038 : : }
1039 : :
1040 : :
1041 : : /* We were asked to return a clone of an existing descriptor. This
1042 : : function must be called with the lock on the parent descriptor
1043 : : being held. */
1044 : : static Elf *
1045 : 7265 : dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1046 : : {
1047 : 7265 : struct Elf *result;
1048 : :
1049 [ + + ]: 7265 : if (fildes == -1)
1050 : : /* Allow the user to pass -1 as the file descriptor for the new file. */
1051 : 10 : fildes = ref->fildes;
1052 : : /* The file descriptor better should be the same. If it was disconnected
1053 : : already (using `elf_cntl') we do not test it. */
1054 [ + - - + ]: 7255 : else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
1055 : : {
1056 : 0 : __libelf_seterrno (ELF_E_FD_MISMATCH);
1057 : 0 : return NULL;
1058 : : }
1059 : :
1060 : : /* The mode must allow reading. I.e., a descriptor creating with a
1061 : : command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
1062 : : not allowed. */
1063 [ + + + - : 7265 : if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
+ - + - +
- - + ]
1064 : : && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1065 : : && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1066 : : && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1067 : : {
1068 : 0 : __libelf_seterrno (ELF_E_INVALID_OP);
1069 : 0 : return NULL;
1070 : : }
1071 : :
1072 : : /* Now it is time to distinguish between reading normal files and
1073 : : archives. Normal files can easily be handled be incrementing the
1074 : : reference counter and return the same descriptor. */
1075 [ - + ]: 7265 : if (ref->kind != ELF_K_AR)
1076 : : {
1077 : 0 : ++ref->ref_count;
1078 : 0 : return ref;
1079 : : }
1080 : :
1081 : : /* This is an archive. We must create a descriptor for the archive
1082 : : member the internal pointer of the archive file descriptor is
1083 : : pointing to. First read the header of the next member if this
1084 : : has not happened already. */
1085 [ + + ]: 7265 : if (ref->state.ar.elf_ar_hdr.ar_name == NULL
1086 [ + + ]: 136 : && __libelf_next_arhdr_wrlock (ref) != 0)
1087 : : /* Something went wrong. Maybe there is no member left. */
1088 : : return NULL;
1089 : :
1090 : : /* We have all the information we need about the next archive member.
1091 : : Now create a descriptor for it. */
1092 : 14528 : result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1093 : 7264 : ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
1094 : :
1095 : : /* Enlist this new descriptor in the list of children. */
1096 [ + - ]: 7264 : if (result != NULL)
1097 : : {
1098 : 7264 : result->next = ref->state.ar.children;
1099 : 7264 : ref->state.ar.children = result;
1100 : : }
1101 : :
1102 : : return result;
1103 : : }
1104 : :
1105 : :
1106 : : /* Return descriptor for empty file ready for writing. */
1107 : : static struct Elf *
1108 : 526 : write_file (int fd, Elf_Cmd cmd)
1109 : : {
1110 : : /* We simply create an empty `Elf' structure. */
1111 : : #define NSCNSALLOC 10
1112 : 526 : Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
1113 : : NSCNSALLOC * sizeof (Elf_Scn));
1114 : :
1115 [ + - ]: 526 : if (result != NULL)
1116 : : {
1117 : : /* We have to write to the file in any case. */
1118 : 526 : result->flags = ELF_F_DIRTY;
1119 : :
1120 : : /* Some more or less arbitrary value. */
1121 : 526 : result->state.elf.scnincr = NSCNSALLOC;
1122 : :
1123 : : /* We have allocated room for some sections. */
1124 : 526 : assert (offsetof (struct Elf, state.elf32.scns)
1125 : : == offsetof (struct Elf, state.elf64.scns));
1126 : 526 : result->state.elf.scns_last = &result->state.elf32.scns;
1127 : 526 : result->state.elf32.scns.max = NSCNSALLOC;
1128 : : }
1129 : :
1130 : 526 : return result;
1131 : : }
1132 : :
1133 : : /* Lock if necessary before dup an archive. */
1134 : : static inline Elf *
1135 : 7265 : lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1136 : : {
1137 : : /* We need wrlock to dup an archive. */
1138 : 7265 : if (ref->kind == ELF_K_AR)
1139 : : {
1140 : 7265 : rwlock_unlock (ref->lock);
1141 : 7265 : rwlock_wrlock (ref->lock);
1142 : : }
1143 : : /* Duplicate the descriptor. */
1144 : 7265 : return dup_elf (fildes, cmd, ref);
1145 : : }
1146 : :
1147 : : /* Return a descriptor for the file belonging to FILDES. */
1148 : : Elf *
1149 : 16819 : elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1150 : : {
1151 : 16819 : Elf *retval;
1152 : :
1153 [ - + ]: 16819 : if (unlikely (__libelf_version != EV_CURRENT))
1154 : : {
1155 : : /* Version wasn't set so far. */
1156 : 0 : __libelf_seterrno (ELF_E_NO_VERSION);
1157 : 0 : return NULL;
1158 : : }
1159 : :
1160 [ + + ]: 16819 : if (ref != NULL)
1161 : : /* Make sure the descriptor is not suddenly going away. */
1162 : : rwlock_rdlock (ref->lock);
1163 [ - + - - ]: 9536 : else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
1164 : : {
1165 : : /* We cannot do anything productive without a file descriptor. */
1166 : 0 : __libelf_seterrno (ELF_E_INVALID_FILE);
1167 : 0 : return NULL;
1168 : : }
1169 : :
1170 [ + + + + : 16819 : switch (cmd)
- + ]
1171 : : {
1172 : : case ELF_C_NULL:
1173 : : /* We simply return a NULL pointer. */
1174 : : retval = NULL;
1175 : : break;
1176 : :
1177 : 6565 : case ELF_C_READ_MMAP_PRIVATE:
1178 : : /* If we have a reference it must also be opened this way. */
1179 [ + + - + ]: 6565 : if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1180 : : {
1181 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1182 : 0 : retval = NULL;
1183 : 0 : break;
1184 : : }
1185 : 16148 : FALLTHROUGH;
1186 : :
1187 : : case ELF_C_READ:
1188 : : case ELF_C_READ_MMAP:
1189 [ + + ]: 16148 : if (ref != NULL)
1190 : 7265 : retval = lock_dup_elf (fildes, cmd, ref);
1191 : : else
1192 : : /* Create descriptor for existing file. */
1193 : 8883 : retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1194 : : break;
1195 : :
1196 : 127 : case ELF_C_RDWR:
1197 : : case ELF_C_RDWR_MMAP:
1198 : : /* If we have a REF object it must also be opened using this
1199 : : command. */
1200 [ - + ]: 127 : if (ref != NULL)
1201 : : {
1202 [ # # # # : 0 : if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
# # ]
1203 : : && ref->cmd != ELF_C_WRITE
1204 : : && ref->cmd != ELF_C_WRITE_MMAP))
1205 : : {
1206 : : /* This is not ok. REF must also be opened for writing. */
1207 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1208 : 0 : retval = NULL;
1209 : : }
1210 : : else
1211 : 0 : retval = lock_dup_elf (fildes, cmd, ref);
1212 : : }
1213 : : else
1214 : : /* Create descriptor for existing file. */
1215 : 127 : retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1216 : : break;
1217 : :
1218 : 526 : case ELF_C_WRITE:
1219 : : case ELF_C_WRITE_MMAP:
1220 : : /* We ignore REF and prepare a descriptor to write a new file. */
1221 : 526 : retval = write_file (fildes, cmd);
1222 : 526 : break;
1223 : :
1224 : 0 : default:
1225 : 0 : __libelf_seterrno (ELF_E_INVALID_CMD);
1226 : 0 : retval = NULL;
1227 : 0 : break;
1228 : : }
1229 : :
1230 : : /* Release the lock. */
1231 : : if (ref != NULL)
1232 : : rwlock_unlock (ref->lock);
1233 : :
1234 : : return retval;
1235 : : }
1236 : : INTDEF(elf_begin)
|