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