Magellan Linux

Annotation of /trunk/elfutils/patches/elfutils-0.158-robustify.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2367 - (hide annotations) (download)
Thu Jan 16 10:39:21 2014 UTC (10 years, 3 months ago) by niro
File size: 62790 byte(s)
-upstream patches
1 niro 2367 --- elfutils/libdwfl/ChangeLog
2     +++ elfutils/libdwfl/ChangeLog
3     @@ -680,6 +680,11 @@
4     * dwfl_module_getdwarf.c (open_elf): Clear errno before CBFAIL.
5     Reported by Kurt Roeckx <kurt@roeckx.be>.
6    
7     +2011-03-23 Petr Machata <pmachata@redhat.com>
8     +
9     + * relocate.c (relocate_section): Use gelf_fsize instead of relying
10     + on shdr->sh_entsize.
11     +
12     2011-02-11 Roland McGrath <roland@redhat.com>
13    
14     * linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz
15     --- elfutils/libdwfl/relocate.c
16     +++ elfutils/libdwfl/relocate.c
17     @@ -1,5 +1,5 @@
18     /* Relocate debug information.
19     - Copyright (C) 2005-2010 Red Hat, Inc.
20     + Copyright (C) 2005-2011 Red Hat, Inc.
21     This file is part of elfutils.
22    
23     This file is free software; you can redistribute it and/or modify
24     @@ -456,7 +456,10 @@ relocate_section (Dwfl_Module *mod, Elf
25     }
26     }
27    
28     - size_t nrels = shdr->sh_size / shdr->sh_entsize;
29     + size_t sh_entsize
30     + = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
31     + 1, EV_CURRENT);
32     + size_t nrels = shdr->sh_size / sh_entsize;
33     size_t complete = 0;
34     if (shdr->sh_type == SHT_REL)
35     for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
36     @@ -558,7 +561,7 @@ relocate_section (Dwfl_Module *mod, Elf
37     nrels = next;
38     }
39    
40     - shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
41     + shdr->sh_size = reldata->d_size = nrels * sh_entsize;
42     gelf_update_shdr (scn, shdr);
43     }
44    
45     --- elfutils/libelf/ChangeLog
46     +++ elfutils/libelf/ChangeLog
47     @@ -754,10 +754,53 @@
48     If section content hasn't been read yet, do it before looking for the
49     block size. If no section data present, infer size of section header.
50    
51     +2005-05-14 Jakub Jelinek <jakub@redhat.com>
52     +
53     + * libelfP.h (INVALID_NDX): Define.
54     + * gelf_getdyn.c (gelf_getdyn): Use it. Remove ndx < 0 test if any.
55     + * gelf_getlib.c (gelf_getlib): Likewise.
56     + * gelf_getmove.c (gelf_getmove): Likewise.
57     + * gelf_getrel.c (gelf_getrel): Likewise.
58     + * gelf_getrela.c (gelf_getrela): Likewise.
59     + * gelf_getsym.c (gelf_getsym): Likewise.
60     + * gelf_getsyminfo.c (gelf_getsyminfo): Likewise.
61     + * gelf_getsymshndx.c (gelf_getsymshndx): Likewise.
62     + * gelf_getversym.c (gelf_getversym): Likewise.
63     + * gelf_update_dyn.c (gelf_update_dyn): Likewise.
64     + * gelf_update_lib.c (gelf_update_lib): Likewise.
65     + * gelf_update_move.c (gelf_update_move): Likewise.
66     + * gelf_update_rel.c (gelf_update_rel): Likewise.
67     + * gelf_update_rela.c (gelf_update_rela): Likewise.
68     + * gelf_update_sym.c (gelf_update_sym): Likewise.
69     + * gelf_update_syminfo.c (gelf_update_syminfo): Likewise.
70     + * gelf_update_symshndx.c (gelf_update_symshndx): Likewise.
71     + * gelf_update_versym.c (gelf_update_versym): Likewise.
72     + * elf_newscn.c (elf_newscn): Check for overflow.
73     + * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise.
74     + (__elfw2(LIBELFBITS,updatefile)): Likewise.
75     + * elf_begin.c (file_read_elf): Likewise.
76     + * elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise.
77     + * elf_getarsym.c (elf_getarsym): Likewise.
78     + * elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)): Likewise.
79     2005-05-11 Ulrich Drepper <drepper@redhat.com>
80    
81     * elf.h: Update again.
82    
83     +2005-05-17 Jakub Jelinek <jakub@redhat.com>
84     +
85     + * elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header
86     + table fits into object's bounds.
87     + * elf_getshstrndx.c (elf_getshstrndx): Add elf->start_offset to
88     + elf->map_address. Check if first section header fits into object's
89     + bounds.
90     + * elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)):
91     + Check if section header table fits into object's bounds.
92     + * elf_begin.c (get_shnum): Ensure section headers fits into
93     + object's bounds.
94     + (file_read_elf): Make sure scncnt is small enough to allocate both
95     + ElfXX_Shdr and Elf_Scn array. Make sure section and program header
96     + tables fit into object's bounds. Avoid memory leak on failure.
97     +
98     2005-05-09 Ulrich Drepper <drepper@redhat.com>
99    
100     * elf.h: Update from glibc.
101     --- elfutils/libelf/elf32_getphdr.c
102     +++ elfutils/libelf/elf32_getphdr.c
103     @@ -93,6 +93,16 @@ __elfw2(LIBELFBITS,getphdr_wrlock) (elf)
104    
105     if (elf->map_address != NULL)
106     {
107     + /* First see whether the information in the ELF header is
108     + valid and it does not ask for too much. */
109     + if (unlikely (ehdr->e_phoff >= elf->maximum_size)
110     + || unlikely (elf->maximum_size - ehdr->e_phoff < size))
111     + {
112     + /* Something is wrong. */
113     + __libelf_seterrno (ELF_E_INVALID_PHDR);
114     + goto out;
115     + }
116     +
117     /* All the data is already mapped. Use it. */
118     void *file_phdr = ((char *) elf->map_address
119     + elf->start_offset + ehdr->e_phoff);
120     --- elfutils/libelf/elf32_getshdr.c
121     +++ elfutils/libelf/elf32_getshdr.c
122     @@ -60,7 +60,8 @@ load_shdr_wrlock (Elf_Scn *scn)
123     goto out;
124    
125     size_t shnum;
126     - if (__elf_getshdrnum_rdlock (elf, &shnum) != 0)
127     + if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
128     + || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
129     goto out;
130     size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
131    
132     @@ -77,6 +78,16 @@ load_shdr_wrlock (Elf_Scn *scn)
133    
134     if (elf->map_address != NULL)
135     {
136     + /* First see whether the information in the ELF header is
137     + valid and it does not ask for too much. */
138     + if (unlikely (ehdr->e_shoff >= elf->maximum_size)
139     + || unlikely (elf->maximum_size - ehdr->e_shoff < size))
140     + {
141     + /* Something is wrong. */
142     + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
143     + goto free_and_out;
144     + }
145     +
146     ElfW2(LIBELFBITS,Shdr) *notcvt;
147    
148     /* All the data is already mapped. If we could use it
149     --- elfutils/libelf/elf32_newphdr.c
150     +++ elfutils/libelf/elf32_newphdr.c
151     @@ -114,6 +114,12 @@ elfw2(LIBELFBITS,newphdr) (elf, count)
152     || count == PN_XNUM
153     || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
154     {
155     + if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
156     + {
157     + result = NULL;
158     + goto out;
159     + }
160     +
161     /* Allocate a new program header with the appropriate number of
162     elements. */
163     result = (ElfW2(LIBELFBITS,Phdr) *)
164     --- elfutils/libelf/elf32_updatefile.c
165     +++ elfutils/libelf/elf32_updatefile.c
166     @@ -202,6 +202,9 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf
167     /* Write all the sections. Well, only those which are modified. */
168     if (shnum > 0)
169     {
170     + if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
171     + return 1;
172     +
173     Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
174     Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *));
175     char *const shdr_start = ((char *) elf->map_address + elf->start_offset
176     @@ -624,6 +627,10 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf
177     /* Write all the sections. Well, only those which are modified. */
178     if (shnum > 0)
179     {
180     + if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
181     + + sizeof (ElfW2(LIBELFBITS,Shdr)))))
182     + return 1;
183     +
184     off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
185     #if EV_NUM != 2
186     xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
187     --- elfutils/libelf/elf_begin.c
188     +++ elfutils/libelf/elf_begin.c
189     @@ -144,7 +144,8 @@ get_shnum (void *map_address, unsigned c
190    
191     if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
192     {
193     - if (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
194     + if (unlikely (ehdr.e32->e_shoff >= maxsize)
195     + || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
196     /* Cannot read the first section header. */
197     return 0;
198    
199     @@ -192,7 +193,8 @@ get_shnum (void *map_address, unsigned c
200    
201     if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
202     {
203     - if (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
204     + if (unlikely (ehdr.e64->e_shoff >= maxsize)
205     + || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
206     /* Cannot read the first section header. */
207     return 0;
208    
209     @@ -264,6 +266,15 @@ file_read_elf (int fildes, void *map_add
210     /* Could not determine the number of sections. */
211     return NULL;
212    
213     + /* Check for too many sections. */
214     + if (e_ident[EI_CLASS] == ELFCLASS32)
215     + {
216     + if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
217     + return NULL;
218     + }
219     + else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
220     + return NULL;
221     +
222     /* We can now allocate the memory. Even if there are no section headers,
223     we allocate space for a zeroth section in case we need it later. */
224     const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
225     @@ -303,6 +314,16 @@ file_read_elf (int fildes, void *map_add
226     {
227     /* We can use the mmapped memory. */
228     elf->state.elf32.ehdr = ehdr;
229     +
230     + if (unlikely (ehdr->e_shoff >= maxsize)
231     + || unlikely (maxsize - ehdr->e_shoff
232     + < scncnt * sizeof (Elf32_Shdr)))
233     + {
234     + free_and_out:
235     + free (elf);
236     + __libelf_seterrno (ELF_E_INVALID_FILE);
237     + return NULL;
238     + }
239     elf->state.elf32.shdr
240     = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
241    
242     @@ -389,6 +410,11 @@ file_read_elf (int fildes, void *map_add
243     {
244     /* We can use the mmapped memory. */
245     elf->state.elf64.ehdr = ehdr;
246     +
247     + if (unlikely (ehdr->e_shoff >= maxsize)
248     + || unlikely (ehdr->e_shoff
249     + + scncnt * sizeof (Elf32_Shdr) > maxsize))
250     + goto free_and_out;
251     elf->state.elf64.shdr
252     = (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
253    
254     --- elfutils/libelf/elf_getarsym.c
255     +++ elfutils/libelf/elf_getarsym.c
256     @@ -183,6 +183,9 @@ elf_getarsym (elf, ptr)
257     size_t index_size = atol (tmpbuf);
258    
259     if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
260     +#if SIZE_MAX <= 4294967295U
261     + || n >= SIZE_MAX / sizeof (Elf_Arsym)
262     +#endif
263     || n * w > index_size)
264     {
265     /* This index table cannot be right since it does not fit into
266     --- elfutils/libelf/elf_getshdrstrndx.c
267     +++ elfutils/libelf/elf_getshdrstrndx.c
268     @@ -104,10 +104,25 @@ elf_getshdrstrndx (elf, dst)
269     if (elf->map_address != NULL
270     && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
271     && (ALLOW_UNALIGNED
272     - || (((size_t) ((char *) elf->map_address + offset))
273     + || (((size_t) ((char *) elf->map_address
274     + + elf->start_offset + offset))
275     & (__alignof__ (Elf32_Shdr) - 1)) == 0))
276     - /* We can directly access the memory. */
277     - num = ((Elf32_Shdr *) (elf->map_address + offset))->sh_link;
278     + {
279     + /* First see whether the information in the ELF header is
280     + valid and it does not ask for too much. */
281     + if (unlikely (elf->maximum_size - offset
282     + < sizeof (Elf32_Shdr)))
283     + {
284     + /* Something is wrong. */
285     + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
286     + result = -1;
287     + goto out;
288     + }
289     +
290     + /* We can directly access the memory. */
291     + num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
292     + + offset))->sh_link;
293     + }
294     else
295     {
296     /* We avoid reading in all the section headers. Just read
297     @@ -142,10 +157,25 @@ elf_getshdrstrndx (elf, dst)
298     if (elf->map_address != NULL
299     && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
300     && (ALLOW_UNALIGNED
301     - || (((size_t) ((char *) elf->map_address + offset))
302     + || (((size_t) ((char *) elf->map_address
303     + + elf->start_offset + offset))
304     & (__alignof__ (Elf64_Shdr) - 1)) == 0))
305     - /* We can directly access the memory. */
306     - num = ((Elf64_Shdr *) (elf->map_address + offset))->sh_link;
307     + {
308     + /* First see whether the information in the ELF header is
309     + valid and it does not ask for too much. */
310     + if (unlikely (elf->maximum_size - offset
311     + < sizeof (Elf64_Shdr)))
312     + {
313     + /* Something is wrong. */
314     + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
315     + result = -1;
316     + goto out;
317     + }
318     +
319     + /* We can directly access the memory. */
320     + num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
321     + + offset))->sh_link;
322     + }
323     else
324     {
325     /* We avoid reading in all the section headers. Just read
326     --- elfutils/libelf/elf_newscn.c
327     +++ elfutils/libelf/elf_newscn.c
328     @@ -83,10 +83,18 @@ elf_newscn (elf)
329     else
330     {
331     /* We must allocate a new element. */
332     - Elf_ScnList *newp;
333     + Elf_ScnList *newp = NULL;
334    
335     assert (elf->state.elf.scnincr > 0);
336    
337     + if (
338     +#if SIZE_MAX <= 4294967295U
339     + likely (elf->state.elf.scnincr
340     + < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
341     +#else
342     + 1
343     +#endif
344     + )
345     newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
346     + ((elf->state.elf.scnincr *= 2)
347     * sizeof (Elf_Scn)), 1);
348     --- elfutils/libelf/gelf_getdyn.c
349     +++ elfutils/libelf/gelf_getdyn.c
350     @@ -1,5 +1,5 @@
351     /* Get information from dynamic table at the given index.
352     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
353     + Copyright (C) 2000-2009 Red Hat, Inc.
354     This file is part of elfutils.
355     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
356    
357     @@ -72,7 +72,7 @@ gelf_getdyn (data, ndx, dst)
358     table entries has to be adopted. The user better has provided
359     a buffer where we can store the information. While copying the
360     data we are converting the format. */
361     - if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
362     + if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
363     {
364     __libelf_seterrno (ELF_E_INVALID_INDEX);
365     goto out;
366     @@ -93,7 +93,7 @@ gelf_getdyn (data, ndx, dst)
367    
368     /* The data is already in the correct form. Just make sure the
369     index is OK. */
370     - if (unlikely ((ndx + 1) * sizeof (GElf_Dyn) > data_scn->d.d_size))
371     + if (INVALID_NDX (ndx, GElf_Dyn, &data_scn->d))
372     {
373     __libelf_seterrno (ELF_E_INVALID_INDEX);
374     goto out;
375     --- elfutils/libelf/gelf_getlib.c
376     +++ elfutils/libelf/gelf_getlib.c
377     @@ -1,5 +1,5 @@
378     /* Get library from table at the given index.
379     - Copyright (C) 2004 Red Hat, Inc.
380     + Copyright (C) 2004-2009 Red Hat, Inc.
381     This file is part of elfutils.
382     Written by Ulrich Drepper <drepper@redhat.com>, 2004.
383    
384     @@ -65,7 +65,7 @@ gelf_getlib (data, ndx, dst)
385     /* The data is already in the correct form. Just make sure the
386     index is OK. */
387     GElf_Lib *result = NULL;
388     - if (unlikely ((ndx + 1) * sizeof (GElf_Lib) > data->d_size))
389     + if (INVALID_NDX (ndx, GElf_Lib, data))
390     __libelf_seterrno (ELF_E_INVALID_INDEX);
391     else
392     {
393     --- elfutils/libelf/gelf_getmove.c
394     +++ elfutils/libelf/gelf_getmove.c
395     @@ -1,5 +1,5 @@
396     /* Get move structure at the given index.
397     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
398     + Copyright (C) 2000-2009 Red Hat, Inc.
399     This file is part of elfutils.
400     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
401    
402     @@ -62,7 +62,7 @@ gelf_getmove (data, ndx, dst)
403    
404     /* The data is already in the correct form. Just make sure the
405     index is OK. */
406     - if (unlikely ((ndx + 1) * sizeof (GElf_Move) > data->d_size))
407     + if (INVALID_NDX (ndx, GElf_Move, data))
408     {
409     __libelf_seterrno (ELF_E_INVALID_INDEX);
410     goto out;
411     --- elfutils/libelf/gelf_getrela.c
412     +++ elfutils/libelf/gelf_getrela.c
413     @@ -1,5 +1,5 @@
414     /* Get RELA relocation information at given index.
415     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
416     + Copyright (C) 2000-2009 Red Hat, Inc.
417     This file is part of elfutils.
418     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
419    
420     @@ -50,12 +50,6 @@ gelf_getrela (data, ndx, dst)
421     if (data_scn == NULL)
422     return NULL;
423    
424     - if (unlikely (ndx < 0))
425     - {
426     - __libelf_seterrno (ELF_E_INVALID_INDEX);
427     - return NULL;
428     - }
429     -
430     if (unlikely (data_scn->d.d_type != ELF_T_RELA))
431     {
432     __libelf_seterrno (ELF_E_INVALID_HANDLE);
433     @@ -72,7 +66,7 @@ gelf_getrela (data, ndx, dst)
434     if (scn->elf->class == ELFCLASS32)
435     {
436     /* We have to convert the data. */
437     - if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
438     + if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
439     {
440     __libelf_seterrno (ELF_E_INVALID_INDEX);
441     result = NULL;
442     @@ -93,7 +87,7 @@ gelf_getrela (data, ndx, dst)
443     {
444     /* Simply copy the data after we made sure we are actually getting
445     correct data. */
446     - if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
447     + if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
448     {
449     __libelf_seterrno (ELF_E_INVALID_INDEX);
450     result = NULL;
451     --- elfutils/libelf/gelf_getrel.c
452     +++ elfutils/libelf/gelf_getrel.c
453     @@ -1,5 +1,5 @@
454     /* Get REL relocation information at given index.
455     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
456     + Copyright (C) 2000-2009 Red Hat, Inc.
457     This file is part of elfutils.
458     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
459    
460     @@ -50,12 +50,6 @@ gelf_getrel (data, ndx, dst)
461     if (data_scn == NULL)
462     return NULL;
463    
464     - if (unlikely (ndx < 0))
465     - {
466     - __libelf_seterrno (ELF_E_INVALID_INDEX);
467     - return NULL;
468     - }
469     -
470     if (unlikely (data_scn->d.d_type != ELF_T_REL))
471     {
472     __libelf_seterrno (ELF_E_INVALID_HANDLE);
473     @@ -72,7 +66,7 @@ gelf_getrel (data, ndx, dst)
474     if (scn->elf->class == ELFCLASS32)
475     {
476     /* We have to convert the data. */
477     - if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
478     + if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
479     {
480     __libelf_seterrno (ELF_E_INVALID_INDEX);
481     result = NULL;
482     @@ -92,7 +86,7 @@ gelf_getrel (data, ndx, dst)
483     {
484     /* Simply copy the data after we made sure we are actually getting
485     correct data. */
486     - if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
487     + if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
488     {
489     __libelf_seterrno (ELF_E_INVALID_INDEX);
490     result = NULL;
491     --- elfutils/libelf/gelf_getsym.c
492     +++ elfutils/libelf/gelf_getsym.c
493     @@ -1,5 +1,5 @@
494     /* Get symbol information from symbol table at the given index.
495     - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
496     + Copyright (C) 1999-2009 Red Hat, Inc.
497     This file is part of elfutils.
498     Written by Ulrich Drepper <drepper@redhat.com>, 1999.
499    
500     @@ -69,7 +69,7 @@ gelf_getsym (data, ndx, dst)
501     table entries has to be adopted. The user better has provided
502     a buffer where we can store the information. While copying the
503     data we are converting the format. */
504     - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size))
505     + if (INVALID_NDX (ndx, Elf32_Sym, data))
506     {
507     __libelf_seterrno (ELF_E_INVALID_INDEX);
508     goto out;
509     @@ -98,7 +98,7 @@ gelf_getsym (data, ndx, dst)
510    
511     /* The data is already in the correct form. Just make sure the
512     index is OK. */
513     - if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size))
514     + if (INVALID_NDX (ndx, GElf_Sym, data))
515     {
516     __libelf_seterrno (ELF_E_INVALID_INDEX);
517     goto out;
518     --- elfutils/libelf/gelf_getsyminfo.c
519     +++ elfutils/libelf/gelf_getsyminfo.c
520     @@ -1,5 +1,5 @@
521     /* Get additional symbol information from symbol table at the given index.
522     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
523     + Copyright (C) 2000-2009 Red Hat, Inc.
524     This file is part of elfutils.
525     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
526    
527     @@ -63,7 +63,7 @@ gelf_getsyminfo (data, ndx, dst)
528    
529     /* The data is already in the correct form. Just make sure the
530     index is OK. */
531     - if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data->d_size))
532     + if (INVALID_NDX (ndx, GElf_Syminfo, data))
533     {
534     __libelf_seterrno (ELF_E_INVALID_INDEX);
535     goto out;
536     --- elfutils/libelf/gelf_getsymshndx.c
537     +++ elfutils/libelf/gelf_getsymshndx.c
538     @@ -1,6 +1,6 @@
539     /* Get symbol information and separate section index from symbol table
540     at the given index.
541     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
542     + Copyright (C) 2000-2009 Red Hat, Inc.
543     This file is part of elfutils.
544     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
545    
546     @@ -69,7 +69,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
547     section index table. */
548     if (likely (shndxdata_scn != NULL))
549     {
550     - if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
551     + if (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d))
552     {
553     __libelf_seterrno (ELF_E_INVALID_INDEX);
554     goto out;
555     @@ -89,7 +89,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
556     table entries has to be adopted. The user better has provided
557     a buffer where we can store the information. While copying the
558     data we are converting the format. */
559     - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata->d_size))
560     + if (INVALID_NDX (ndx, Elf32_Sym, symdata))
561     {
562     __libelf_seterrno (ELF_E_INVALID_INDEX);
563     goto out;
564     @@ -118,7 +118,7 @@ gelf_getsymshndx (symdata, shndxdata, nd
565    
566     /* The data is already in the correct form. Just make sure the
567     index is OK. */
568     - if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > symdata->d_size))
569     + if (INVALID_NDX (ndx, GElf_Sym, symdata))
570     {
571     __libelf_seterrno (ELF_E_INVALID_INDEX);
572     goto out;
573     --- elfutils/libelf/gelf_getversym.c
574     +++ elfutils/libelf/gelf_getversym.c
575     @@ -1,5 +1,5 @@
576     /* Get symbol version information at the given index.
577     - Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc.
578     + Copyright (C) 1999-2009 Red Hat, Inc.
579     This file is part of elfutils.
580     Written by Ulrich Drepper <drepper@redhat.com>, 1999.
581    
582     @@ -71,7 +71,7 @@ gelf_getversym (data, ndx, dst)
583    
584     /* The data is already in the correct form. Just make sure the
585     index is OK. */
586     - if (unlikely ((ndx + 1) * sizeof (GElf_Versym) > data->d_size))
587     + if (INVALID_NDX (ndx, GElf_Versym, data))
588     {
589     __libelf_seterrno (ELF_E_INVALID_INDEX);
590     result = NULL;
591     --- elfutils/libelf/gelf_update_dyn.c
592     +++ elfutils/libelf/gelf_update_dyn.c
593     @@ -1,5 +1,5 @@
594     /* Update information in dynamic table at the given index.
595     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
596     + Copyright (C) 2000-2009 Red Hat, Inc.
597     This file is part of elfutils.
598     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
599    
600     @@ -50,12 +50,6 @@ gelf_update_dyn (data, ndx, src)
601     if (data == NULL)
602     return 0;
603    
604     - if (unlikely (ndx < 0))
605     - {
606     - __libelf_seterrno (ELF_E_INVALID_INDEX);
607     - return 0;
608     - }
609     -
610     if (unlikely (data_scn->d.d_type != ELF_T_DYN))
611     {
612     /* The type of the data better should match. */
613     @@ -81,7 +75,7 @@ gelf_update_dyn (data, ndx, src)
614     }
615    
616     /* Check whether we have to resize the data buffer. */
617     - if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
618     + if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
619     {
620     __libelf_seterrno (ELF_E_INVALID_INDEX);
621     goto out;
622     @@ -95,7 +89,7 @@ gelf_update_dyn (data, ndx, src)
623     else
624     {
625     /* Check whether we have to resize the data buffer. */
626     - if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size))
627     + if (INVALID_NDX (ndx, Elf64_Dyn, &data_scn->d))
628     {
629     __libelf_seterrno (ELF_E_INVALID_INDEX);
630     goto out;
631     --- elfutils/libelf/gelf_update_lib.c
632     +++ elfutils/libelf/gelf_update_lib.c
633     @@ -1,5 +1,5 @@
634     /* Update library in table at the given index.
635     - Copyright (C) 2004 Red Hat, Inc.
636     + Copyright (C) 2004-2009 Red Hat, Inc.
637     This file is part of elfutils.
638     Written by Ulrich Drepper <drepper@redhat.com>, 2004.
639    
640     @@ -47,12 +47,6 @@ gelf_update_lib (data, ndx, src)
641     if (data == NULL)
642     return 0;
643    
644     - if (unlikely (ndx < 0))
645     - {
646     - __libelf_seterrno (ELF_E_INVALID_INDEX);
647     - return 0;
648     - }
649     -
650     Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
651     if (unlikely (data_scn->d.d_type != ELF_T_LIB))
652     {
653     @@ -66,7 +60,7 @@ gelf_update_lib (data, ndx, src)
654    
655     /* Check whether we have to resize the data buffer. */
656     int result = 0;
657     - if (unlikely ((ndx + 1) * sizeof (Elf64_Lib) > data_scn->d.d_size))
658     + if (INVALID_NDX (ndx, Elf64_Lib, &data_scn->d))
659     __libelf_seterrno (ELF_E_INVALID_INDEX);
660     else
661     {
662     --- elfutils/libelf/gelf_update_move.c
663     +++ elfutils/libelf/gelf_update_move.c
664     @@ -1,5 +1,5 @@
665     /* Update move structure at the given index.
666     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
667     + Copyright (C) 2000-2009 Red Hat, Inc.
668     This file is part of elfutils.
669     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
670    
671     @@ -54,8 +54,7 @@ gelf_update_move (data, ndx, src)
672     assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
673    
674     /* Check whether we have to resize the data buffer. */
675     - if (unlikely (ndx < 0)
676     - || unlikely ((ndx + 1) * sizeof (GElf_Move) > data_scn->d.d_size))
677     + if (INVALID_NDX (ndx, GElf_Move, &data_scn->d))
678     {
679     __libelf_seterrno (ELF_E_INVALID_INDEX);
680     return 0;
681     --- elfutils/libelf/gelf_update_rela.c
682     +++ elfutils/libelf/gelf_update_rela.c
683     @@ -1,5 +1,5 @@
684     /* Update RELA relocation information at given index.
685     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
686     + Copyright (C) 2000-2009 Red Hat, Inc.
687     This file is part of elfutils.
688     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
689    
690     @@ -47,12 +47,6 @@ gelf_update_rela (Elf_Data *dst, int ndx
691     if (dst == NULL)
692     return 0;
693    
694     - if (unlikely (ndx < 0))
695     - {
696     - __libelf_seterrno (ELF_E_INVALID_INDEX);
697     - return 0;
698     - }
699     -
700     if (unlikely (data_scn->d.d_type != ELF_T_RELA))
701     {
702     /* The type of the data better should match. */
703     @@ -80,7 +74,7 @@ gelf_update_rela (Elf_Data *dst, int ndx
704     }
705    
706     /* Check whether we have to resize the data buffer. */
707     - if (unlikely ((ndx + 1) * sizeof (Elf32_Rela) > data_scn->d.d_size))
708     + if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
709     {
710     __libelf_seterrno (ELF_E_INVALID_INDEX);
711     goto out;
712     @@ -96,7 +90,7 @@ gelf_update_rela (Elf_Data *dst, int ndx
713     else
714     {
715     /* Check whether we have to resize the data buffer. */
716     - if (unlikely ((ndx + 1) * sizeof (Elf64_Rela) > data_scn->d.d_size))
717     + if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
718     {
719     __libelf_seterrno (ELF_E_INVALID_INDEX);
720     goto out;
721     --- elfutils/libelf/gelf_update_rel.c
722     +++ elfutils/libelf/gelf_update_rel.c
723     @@ -1,5 +1,5 @@
724     /* Update REL relocation information at given index.
725     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
726     + Copyright (C) 2000-2009 Red Hat, Inc.
727     This file is part of elfutils.
728     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
729    
730     @@ -47,12 +47,6 @@ gelf_update_rel (Elf_Data *dst, int ndx,
731     if (dst == NULL)
732     return 0;
733    
734     - if (unlikely (ndx < 0))
735     - {
736     - __libelf_seterrno (ELF_E_INVALID_INDEX);
737     - return 0;
738     - }
739     -
740     if (unlikely (data_scn->d.d_type != ELF_T_REL))
741     {
742     /* The type of the data better should match. */
743     @@ -78,7 +72,7 @@ gelf_update_rel (Elf_Data *dst, int ndx,
744     }
745    
746     /* Check whether we have to resize the data buffer. */
747     - if (unlikely ((ndx + 1) * sizeof (Elf32_Rel) > data_scn->d.d_size))
748     + if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
749     {
750     __libelf_seterrno (ELF_E_INVALID_INDEX);
751     goto out;
752     @@ -93,7 +87,7 @@ gelf_update_rel (Elf_Data *dst, int ndx,
753     else
754     {
755     /* Check whether we have to resize the data buffer. */
756     - if (unlikely ((ndx + 1) * sizeof (Elf64_Rel) > data_scn->d.d_size))
757     + if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
758     {
759     __libelf_seterrno (ELF_E_INVALID_INDEX);
760     goto out;
761     --- elfutils/libelf/gelf_update_sym.c
762     +++ elfutils/libelf/gelf_update_sym.c
763     @@ -1,5 +1,5 @@
764     /* Update symbol information in symbol table at the given index.
765     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
766     + Copyright (C) 2000-2009 Red Hat, Inc.
767     This file is part of elfutils.
768     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
769    
770     @@ -51,12 +51,6 @@ gelf_update_sym (data, ndx, src)
771     if (data == NULL)
772     return 0;
773    
774     - if (unlikely (ndx < 0))
775     - {
776     - __libelf_seterrno (ELF_E_INVALID_INDEX);
777     - return 0;
778     - }
779     -
780     if (unlikely (data_scn->d.d_type != ELF_T_SYM))
781     {
782     /* The type of the data better should match. */
783     @@ -81,7 +75,7 @@ gelf_update_sym (data, ndx, src)
784     }
785    
786     /* Check whether we have to resize the data buffer. */
787     - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data_scn->d.d_size))
788     + if (INVALID_NDX (ndx, Elf32_Sym, &data_scn->d))
789     {
790     __libelf_seterrno (ELF_E_INVALID_INDEX);
791     goto out;
792     @@ -104,7 +98,7 @@ gelf_update_sym (data, ndx, src)
793     else
794     {
795     /* Check whether we have to resize the data buffer. */
796     - if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > data_scn->d.d_size))
797     + if (INVALID_NDX (ndx, Elf64_Sym, &data_scn->d))
798     {
799     __libelf_seterrno (ELF_E_INVALID_INDEX);
800     goto out;
801     --- elfutils/libelf/gelf_update_syminfo.c
802     +++ elfutils/libelf/gelf_update_syminfo.c
803     @@ -1,5 +1,5 @@
804     /* Update additional symbol information in symbol table at the given index.
805     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
806     + Copyright (C) 2000-2009 Red Hat, Inc.
807     This file is part of elfutils.
808     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
809    
810     @@ -51,12 +51,6 @@ gelf_update_syminfo (data, ndx, src)
811     if (data == NULL)
812     return 0;
813    
814     - if (unlikely (ndx < 0))
815     - {
816     - __libelf_seterrno (ELF_E_INVALID_INDEX);
817     - return 0;
818     - }
819     -
820     if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
821     {
822     /* The type of the data better should match. */
823     @@ -72,7 +66,7 @@ gelf_update_syminfo (data, ndx, src)
824     rwlock_wrlock (scn->elf->lock);
825    
826     /* Check whether we have to resize the data buffer. */
827     - if (unlikely ((ndx + 1) * sizeof (GElf_Syminfo) > data_scn->d.d_size))
828     + if (INVALID_NDX (ndx, GElf_Syminfo, &data_scn->d))
829     {
830     __libelf_seterrno (ELF_E_INVALID_INDEX);
831     goto out;
832     --- elfutils/libelf/gelf_update_symshndx.c
833     +++ elfutils/libelf/gelf_update_symshndx.c
834     @@ -1,6 +1,6 @@
835     /* Update symbol information and section index in symbol table at the
836     given index.
837     - Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
838     + Copyright (C) 2000-2009 Red Hat, Inc.
839     This file is part of elfutils.
840     Written by Ulrich Drepper <drepper@redhat.com>, 2000.
841    
842     @@ -56,12 +56,6 @@ gelf_update_symshndx (symdata, shndxdata
843     if (symdata == NULL)
844     return 0;
845    
846     - if (unlikely (ndx < 0))
847     - {
848     - __libelf_seterrno (ELF_E_INVALID_INDEX);
849     - return 0;
850     - }
851     -
852     if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
853     {
854     /* The type of the data better should match. */
855     @@ -107,7 +101,7 @@ gelf_update_symshndx (symdata, shndxdata
856     }
857    
858     /* Check whether we have to resize the data buffer. */
859     - if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > symdata_scn->d.d_size))
860     + if (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d))
861     {
862     __libelf_seterrno (ELF_E_INVALID_INDEX);
863     goto out;
864     @@ -130,7 +124,7 @@ gelf_update_symshndx (symdata, shndxdata
865     else
866     {
867     /* Check whether we have to resize the data buffer. */
868     - if (unlikely ((ndx + 1) * sizeof (Elf64_Sym) > symdata_scn->d.d_size))
869     + if (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d))
870     {
871     __libelf_seterrno (ELF_E_INVALID_INDEX);
872     goto out;
873     --- elfutils/libelf/gelf_update_versym.c
874     +++ elfutils/libelf/gelf_update_versym.c
875     @@ -1,5 +1,5 @@
876     /* Update symbol version information.
877     - Copyright (C) 2001, 2002 Red Hat, Inc.
878     + Copyright (C) 2001-2009 Red Hat, Inc.
879     This file is part of elfutils.
880     Written by Ulrich Drepper <drepper@redhat.com>, 2001.
881    
882     @@ -54,8 +54,7 @@ gelf_update_versym (data, ndx, src)
883     assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
884    
885     /* Check whether we have to resize the data buffer. */
886     - if (unlikely (ndx < 0)
887     - || unlikely ((ndx + 1) * sizeof (GElf_Versym) > data_scn->d.d_size))
888     + if (INVALID_NDX (ndx, GElf_Versym, &data_scn->d))
889     {
890     __libelf_seterrno (ELF_E_INVALID_INDEX);
891     return 0;
892     --- elfutils/libelf/libelfP.h
893     +++ elfutils/libelf/libelfP.h
894     @@ -587,4 +587,8 @@ extern uint32_t __libelf_crc32 (uint32_t
895     /* Align offset to 4 bytes as needed for note name and descriptor data. */
896     #define NOTE_ALIGN(n) (((n) + 3) & -4U)
897    
898     +/* Convenience macro. */
899     +#define INVALID_NDX(ndx, type, data) \
900     + unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
901     +
902     #endif /* libelfP.h */
903     --- elfutils/src/ChangeLog
904     +++ elfutils/src/ChangeLog
905     @@ -702,6 +702,12 @@
906    
907     * readelf.c (dwarf_attr_string): Grok DW_AT_GNU_odr_signature.
908    
909     +2011-03-23 Petr Machata <pmachata@redhat.com>
910     +
911     + * readelf.c (handle_dynamic, handle_relocs_rel)
912     + (handle_relocs_rela, handle_versym, print_liblist):
913     + Use gelf_fsize instead of relying on shdr->sh_entsize.
914     +
915     2011-02-11 Roland McGrath <roland@redhat.com>
916    
917     * elfcmp.c (verbose): New variable.
918     @@ -2414,6 +2420,16 @@
919     object symbols or symbols with unknown type.
920     (check_rel): Likewise.
921    
922     +2005-06-09 Roland McGrath <roland@redhat.com>
923     +
924     + * readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link.
925     + (handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise.
926     + (handle_scngrp): Check for bogus sh_info.
927     +
928     + * strip.c (handle_elf): Check for bogus values in sh_link, sh_info,
929     + st_shndx, e_shstrndx, and SHT_GROUP or SHT_SYMTAB_SHNDX data.
930     + Don't use assert on input values, instead bail with "illformed" error.
931     +
932     2005-06-08 Roland McGrath <roland@redhat.com>
933    
934     * readelf.c (print_ops): Add consts.
935     @@ -2459,6 +2475,19 @@
936    
937     * readelf.c (dwarf_tag_string): Add new tags.
938    
939     +2005-05-17 Jakub Jelinek <jakub@redhat.com>
940     +
941     + * elflint.c (check_hash): Don't check entries beyond end of section.
942     + (check_note): Don't crash if gelf_rawchunk fails.
943     + (section_name): Return <invalid> if gelf_getshdr returns NULL.
944     +
945     +2005-05-14 Jakub Jelinek <jakub@redhat.com>
946     +
947     + * elflint.c (section_name): Return "<invalid>" instead of
948     + crashing on invalid section name.
949     + (check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic,
950     + check_symtab_shndx, check_hash, check_versym): Robustify.
951     +
952     2005-05-08 Roland McGrath <roland@redhat.com>
953    
954     * strip.c (handle_elf): Don't translate hash and versym data formats,
955     --- elfutils/src/elflint.c
956     +++ elfutils/src/elflint.c
957     @@ -123,6 +123,10 @@ static uint32_t shstrndx;
958     /* Array to count references in section groups. */
959     static int *scnref;
960    
961     +/* Numbers of sections and program headers. */
962     +static unsigned int shnum;
963     +static unsigned int phnum;
964     +
965    
966     int
967     main (int argc, char *argv[])
968     @@ -311,10 +315,19 @@ section_name (Ebl *ebl, int idx)
969     {
970     GElf_Shdr shdr_mem;
971     GElf_Shdr *shdr;
972     + const char *ret;
973     +
974     + if ((unsigned int) idx > shnum)
975     + return "<invalid>";
976    
977     shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
978     + if (shdr == NULL)
979     + return "<invalid>";
980    
981     - return elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
982     + ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
983     + if (ret == NULL)
984     + return "<invalid>";
985     + return ret;
986     }
987    
988    
989     @@ -337,11 +350,6 @@ static const int valid_e_machine[] =
990     (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
991    
992    
993     -/* Numbers of sections and program headers. */
994     -static unsigned int shnum;
995     -static unsigned int phnum;
996     -
997     -
998     static void
999     check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
1000     {
1001     @@ -625,7 +633,8 @@ section [%2d] '%s': symbol table cannot
1002     }
1003     }
1004    
1005     - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
1006     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
1007     + if (shdr->sh_entsize != sh_entsize)
1008     ERROR (gettext ("\
1009     section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
1010     idx, section_name (ebl, idx));
1011     @@ -663,7 +672,7 @@ section [%2d] '%s': XINDEX for zeroth en
1012     xndxscnidx, section_name (ebl, xndxscnidx));
1013     }
1014    
1015     - for (size_t cnt = 1; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1016     + for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt)
1017     {
1018     sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
1019     if (sym == NULL)
1020     @@ -683,7 +692,8 @@ section [%2d] '%s': symbol %zu: invalid
1021     else
1022     {
1023     name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
1024     - assert (name != NULL);
1025     + assert (name != NULL
1026     + || strshdr->sh_type != SHT_STRTAB);
1027     }
1028    
1029     if (sym->st_shndx == SHN_XINDEX)
1030     @@ -1040,9 +1050,11 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
1031     {
1032     GElf_Shdr rcshdr_mem;
1033     const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
1034     - assert (rcshdr != NULL);
1035    
1036     - if (rcshdr->sh_type == SHT_DYNAMIC)
1037     + if (rcshdr == NULL)
1038     + break;
1039     +
1040     + if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize)
1041     {
1042     /* Found the dynamic section. Look through it. */
1043     Elf_Data *d = elf_getdata (scn, NULL);
1044     @@ -1052,7 +1064,9 @@ is_rel_dyn (Ebl *ebl, const GElf_Ehdr *e
1045     {
1046     GElf_Dyn dyn_mem;
1047     GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
1048     - assert (dyn != NULL);
1049     +
1050     + if (dyn == NULL)
1051     + break;
1052    
1053     if (dyn->d_tag == DT_RELCOUNT)
1054     {
1055     @@ -1066,7 +1080,9 @@ section [%2d] '%s': DT_RELCOUNT used for
1056     /* Does the number specified number of relative
1057     relocations exceed the total number of
1058     relocations? */
1059     - if (dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
1060     + if (shdr->sh_entsize != 0
1061     + && dyn->d_un.d_val > (shdr->sh_size
1062     + / shdr->sh_entsize))
1063     ERROR (gettext ("\
1064     section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
1065     idx, section_name (ebl, idx),
1066     @@ -1226,7 +1242,8 @@ section [%2d] '%s': no relocations for m
1067     }
1068     }
1069    
1070     - if (shdr->sh_entsize != gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT))
1071     + size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
1072     + if (shdr->sh_entsize != sh_entsize)
1073     ERROR (gettext (reltype == ELF_T_RELA ? "\
1074     section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
1075     section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
1076     @@ -1449,7 +1466,8 @@ check_rela (Ebl *ebl, GElf_Ehdr *ehdr, G
1077     Elf_Data *symdata = elf_getdata (symscn, NULL);
1078     enum load_state state = state_undecided;
1079    
1080     - for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1081     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1082     + for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1083     {
1084     GElf_Rela rela_mem;
1085     GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
1086     @@ -1499,7 +1517,8 @@ check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GE
1087     Elf_Data *symdata = elf_getdata (symscn, NULL);
1088     enum load_state state = state_undecided;
1089    
1090     - for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1091     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1092     + for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1093     {
1094     GElf_Rel rel_mem;
1095     GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
1096     @@ -1598,7 +1617,8 @@ section [%2d] '%s': referenced as string
1097     shdr->sh_link, section_name (ebl, shdr->sh_link),
1098     idx, section_name (ebl, idx));
1099    
1100     - if (shdr->sh_entsize != gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT))
1101     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1102     + if (shdr->sh_entsize != sh_entsize)
1103     ERROR (gettext ("\
1104     section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
1105     idx, section_name (ebl, idx));
1106     @@ -1608,7 +1628,7 @@ section [%2d] '%s': section entry size d
1107     idx, section_name (ebl, idx));
1108    
1109     bool non_null_warned = false;
1110     - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1111     + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1112     {
1113     GElf_Dyn dyn_mem;
1114     GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
1115     @@ -1880,6 +1900,8 @@ section [%2d] '%s': entry size does not
1116     idx, section_name (ebl, idx));
1117    
1118     if (symshdr != NULL
1119     + && shdr->sh_entsize
1120     + && symshdr->sh_entsize
1121     && (shdr->sh_size / shdr->sh_entsize
1122     < symshdr->sh_size / symshdr->sh_entsize))
1123     ERROR (gettext ("\
1124     @@ -1906,6 +1928,12 @@ section [%2d] '%s': extended section ind
1125     }
1126    
1127     Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
1128     + if (data == NULL)
1129     + {
1130     + ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
1131     + idx, section_name (ebl, idx));
1132     + return;
1133     + }
1134    
1135     if (*((Elf32_Word *) data->d_buf) != 0)
1136     ERROR (gettext ("symbol 0 should have zero extended section index\n"));
1137     @@ -1948,7 +1976,7 @@ section [%2d] '%s': hash table section i
1138    
1139     size_t maxidx = nchain;
1140    
1141     - if (symshdr != NULL)
1142     + if (symshdr != NULL && symshdr->sh_entsize != 0)
1143     {
1144     size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
1145    
1146     @@ -1959,18 +1987,28 @@ section [%2d] '%s': hash table section i
1147     maxidx = symsize;
1148     }
1149    
1150     + Elf32_Word *buf = (Elf32_Word *) data->d_buf;
1151     + Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size);
1152     size_t cnt;
1153     for (cnt = 2; cnt < 2 + nbucket; ++cnt)
1154     - if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
1155     + {
1156     + if (buf + cnt >= end)
1157     + break;
1158     + else if (buf[cnt] >= maxidx)
1159     ERROR (gettext ("\
1160     section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
1161     idx, section_name (ebl, idx), cnt - 2);
1162     + }
1163    
1164     for (; cnt < 2 + nbucket + nchain; ++cnt)
1165     - if (((Elf32_Word *) data->d_buf)[cnt] >= maxidx)
1166     + {
1167     + if (buf + cnt >= end)
1168     + break;
1169     + else if (buf[cnt] >= maxidx)
1170     ERROR (gettext ("\
1171     section [%2d] '%s': hash chain reference %zu out of bounds\n"),
1172     idx, section_name (ebl, idx), cnt - 2 - nbucket);
1173     + }
1174     }
1175    
1176    
1177     @@ -2000,18 +2038,28 @@ section [%2d] '%s': hash table section i
1178     maxidx = symsize;
1179     }
1180    
1181     + Elf64_Xword *buf = (Elf64_Xword *) data->d_buf;
1182     + Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size);
1183     size_t cnt;
1184     for (cnt = 2; cnt < 2 + nbucket; ++cnt)
1185     - if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
1186     + {
1187     + if (buf + cnt >= end)
1188     + break;
1189     + else if (buf[cnt] >= maxidx)
1190     ERROR (gettext ("\
1191     section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
1192     idx, section_name (ebl, idx), cnt - 2);
1193     + }
1194    
1195     for (; cnt < 2 + nbucket + nchain; ++cnt)
1196     - if (((Elf64_Xword *) data->d_buf)[cnt] >= maxidx)
1197     + {
1198     + if (buf + cnt >= end)
1199     + break;
1200     + else if (buf[cnt] >= maxidx)
1201     ERROR (gettext ("\
1202     section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"),
1203     - idx, section_name (ebl, idx), (uint64_t) (cnt - 2 - nbucket));
1204     + idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket);
1205     + }
1206     }
1207    
1208    
1209     @@ -2036,7 +2084,7 @@ section [%2d] '%s': bitmask size not pow
1210     if (shdr->sh_size < (4 + bitmask_words + nbuckets) * sizeof (Elf32_Word))
1211     {
1212     ERROR (gettext ("\
1213     -section [%2d] '%s': hash table section is too small (is %ld, expected at least%ld)\n"),
1214     +section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"),
1215     idx, section_name (ebl, idx), (long int) shdr->sh_size,
1216     (long int) ((4 + bitmask_words + nbuckets) * sizeof (Elf32_Word)));
1217     return;
1218     @@ -2708,8 +2756,9 @@ section [%2d] '%s' refers in sh_link to
1219    
1220     /* The number of elements in the version symbol table must be the
1221     same as the number of symbols. */
1222     - if (shdr->sh_size / shdr->sh_entsize
1223     - != symshdr->sh_size / symshdr->sh_entsize)
1224     + if (shdr->sh_entsize && symshdr->sh_entsize
1225     + && (shdr->sh_size / shdr->sh_entsize
1226     + != symshdr->sh_size / symshdr->sh_entsize))
1227     ERROR (gettext ("\
1228     section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
1229     idx, section_name (ebl, idx),
1230     --- elfutils/src/readelf.c
1231     +++ elfutils/src/readelf.c
1232     @@ -1364,6 +1364,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
1233     Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1234    
1235     GElf_Sym sym_mem;
1236     + GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1237     +
1238     printf ((grpref[0] & GRP_COMDAT)
1239     ? ngettext ("\
1240     \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1241     @@ -1376,8 +1378,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, G
1242     data->d_size / sizeof (Elf32_Word) - 1),
1243     elf_ndxscn (scn),
1244     elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1245     - elf_strptr (ebl->elf, symshdr->sh_link,
1246     - gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name)
1247     + (sym == NULL ? NULL
1248     + : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1249     ?: gettext ("<INVALID SYMBOL>"),
1250     data->d_size / sizeof (Elf32_Word) - 1);
1251    
1252     @@ -1528,10 +1530,12 @@ static void
1253     handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1254     {
1255     int class = gelf_getclass (ebl->elf);
1256     - GElf_Shdr glink;
1257     + GElf_Shdr glink_mem;
1258     + GElf_Shdr *glink;
1259     Elf_Data *data;
1260     size_t cnt;
1261     size_t shstrndx;
1262     + size_t sh_entsize;
1263    
1264     /* Get the data of the section. */
1265     data = elf_getdata (scn, NULL);
1266     @@ -1543,21 +1547,26 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn,
1267     error (EXIT_FAILURE, 0,
1268     gettext ("cannot get section header string table index"));
1269    
1270     + sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1271     +
1272     + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1273     + if (glink == NULL)
1274     + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1275     + elf_ndxscn (scn));
1276     +
1277     printf (ngettext ("\
1278     \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1279     "\
1280     \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1281     - shdr->sh_size / shdr->sh_entsize),
1282     - (unsigned long int) (shdr->sh_size / shdr->sh_entsize),
1283     + shdr->sh_size / sh_entsize),
1284     + (unsigned long int) (shdr->sh_size / sh_entsize),
1285     class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1286     shdr->sh_offset,
1287     (int) shdr->sh_link,
1288     - elf_strptr (ebl->elf, shstrndx,
1289     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1290     - &glink)->sh_name));
1291     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1292     fputs_unlocked (gettext (" Type Value\n"), stdout);
1293    
1294     - for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1295     + for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1296     {
1297     GElf_Dyn dynmem;
1298     GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1299     @@ -1706,7 +1715,8 @@ static void
1300     handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1301     {
1302     int class = gelf_getclass (ebl->elf);
1303     - int nentries = shdr->sh_size / shdr->sh_entsize;
1304     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1305     + int nentries = shdr->sh_size / sh_entsize;
1306    
1307     /* Get the data of the section. */
1308     Elf_Data *data = elf_getdata (scn, NULL);
1309     @@ -1892,7 +1902,8 @@ static void
1310     handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1311     {
1312     int class = gelf_getclass (ebl->elf);
1313     - int nentries = shdr->sh_size / shdr->sh_entsize;
1314     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
1315     + int nentries = shdr->sh_size / sh_entsize;
1316    
1317     /* Get the data of the section. */
1318     Elf_Data *data = elf_getdata (scn, NULL);
1319     @@ -2139,6 +2150,13 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
1320     error (EXIT_FAILURE, 0,
1321     gettext ("cannot get section header string table index"));
1322    
1323     + GElf_Shdr glink_mem;
1324     + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1325     + &glink_mem);
1326     + if (glink == NULL)
1327     + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1328     + elf_ndxscn (scn));
1329     +
1330     /* Now we can compute the number of entries in the section. */
1331     unsigned int nsyms = data->d_size / (class == ELFCLASS32
1332     ? sizeof (Elf32_Sym)
1333     @@ -2149,15 +2167,12 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, G
1334     nsyms),
1335     (unsigned int) elf_ndxscn (scn),
1336     elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
1337     - GElf_Shdr glink;
1338     printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
1339     " %lu local symbols String table: [%2u] '%s'\n",
1340     shdr->sh_info),
1341     (unsigned long int) shdr->sh_info,
1342     (unsigned int) shdr->sh_link,
1343     - elf_strptr (ebl->elf, shstrndx,
1344     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1345     - &glink)->sh_name));
1346     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1347    
1348     fputs_unlocked (class == ELFCLASS32
1349     ? gettext ("\
1350     @@ -2393,7 +2408,13 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
1351     error (EXIT_FAILURE, 0,
1352     gettext ("cannot get section header string table index"));
1353    
1354     - GElf_Shdr glink;
1355     + GElf_Shdr glink_mem;
1356     + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1357     + &glink_mem);
1358     + if (glink == NULL)
1359     + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1360     + elf_ndxscn (scn));
1361     +
1362     printf (ngettext ("\
1363     \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1364     "\
1365     @@ -2404,9 +2425,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn,
1366     class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1367     shdr->sh_offset,
1368     (unsigned int) shdr->sh_link,
1369     - elf_strptr (ebl->elf, shstrndx,
1370     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1371     - &glink)->sh_name));
1372     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1373    
1374     unsigned int offset = 0;
1375     for (int cnt = shdr->sh_info; --cnt >= 0; )
1376     @@ -2459,8 +2478,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
1377     error (EXIT_FAILURE, 0,
1378     gettext ("cannot get section header string table index"));
1379    
1380     + GElf_Shdr glink_mem;
1381     + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1382     + &glink_mem);
1383     + if (glink == NULL)
1384     + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1385     + elf_ndxscn (scn));
1386     +
1387     int class = gelf_getclass (ebl->elf);
1388     - GElf_Shdr glink;
1389     printf (ngettext ("\
1390     \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1391     "\
1392     @@ -2472,9 +2497,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, G
1393     class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1394     shdr->sh_offset,
1395     (unsigned int) shdr->sh_link,
1396     - elf_strptr (ebl->elf, shstrndx,
1397     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1398     - &glink)->sh_name));
1399     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1400    
1401     unsigned int offset = 0;
1402     for (int cnt = shdr->sh_info; --cnt >= 0; )
1403     @@ -2736,25 +2759,30 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, G
1404     filename = NULL;
1405     }
1406    
1407     + GElf_Shdr glink_mem;
1408     + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1409     + &glink_mem);
1410     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
1411     + if (glink == NULL)
1412     + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"),
1413     + elf_ndxscn (scn));
1414     +
1415     /* Print the header. */
1416     - GElf_Shdr glink;
1417     printf (ngettext ("\
1418     \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
1419     "\
1420     \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
1421     - shdr->sh_size / shdr->sh_entsize),
1422     + shdr->sh_size / sh_entsize),
1423     (unsigned int) elf_ndxscn (scn),
1424     elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1425     - (int) (shdr->sh_size / shdr->sh_entsize),
1426     + (int) (shdr->sh_size / sh_entsize),
1427     class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1428     shdr->sh_offset,
1429     (unsigned int) shdr->sh_link,
1430     - elf_strptr (ebl->elf, shstrndx,
1431     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1432     - &glink)->sh_name));
1433     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1434    
1435     /* Now we can finally look at the actual contents of this section. */
1436     - for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
1437     + for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1438     {
1439     if (cnt % 2 == 0)
1440     printf ("\n %4d:", cnt);
1441     @@ -2803,7 +2831,17 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn,
1442     for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
1443     ++counts[lengths[cnt]];
1444    
1445     - GElf_Shdr glink;
1446     + GElf_Shdr glink_mem;
1447     + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
1448     + shdr->sh_link),
1449     + &glink_mem);
1450     + if (glink == NULL)
1451     + {
1452     + error (0, 0, gettext ("invalid sh_link value in section %Zu"),
1453     + elf_ndxscn (scn));
1454     + return;
1455     + }
1456     +
1457     printf (ngettext ("\
1458     \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1459     "\
1460     @@ -2816,9 +2854,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn,
1461     shdr->sh_addr,
1462     shdr->sh_offset,
1463     (unsigned int) shdr->sh_link,
1464     - elf_strptr (ebl->elf, shstrndx,
1465     - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
1466     - &glink)->sh_name));
1467     + elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1468    
1469     if (extrastr != NULL)
1470     fputs (extrastr, stdout);
1471     @@ -3078,7 +3114,8 @@ print_liblist (Ebl *ebl)
1472    
1473     if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
1474     {
1475     - int nentries = shdr->sh_size / shdr->sh_entsize;
1476     + size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
1477     + int nentries = shdr->sh_size / sh_entsize;
1478     printf (ngettext ("\
1479     \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1480     "\
1481     @@ -4398,6 +4435,16 @@ print_decoded_aranges_section (Ebl *ebl,
1482     return;
1483     }
1484    
1485     + GElf_Shdr glink_mem;
1486     + GElf_Shdr *glink;
1487     + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1488     + if (glink == NULL)
1489     + {
1490     + error (0, 0, gettext ("invalid sh_link value in section %Zu"),
1491     + elf_ndxscn (scn));
1492     + return;
1493     + }
1494     +
1495     printf (ngettext ("\
1496     \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
1497     "\
1498     --- elfutils/src/strip.c
1499     +++ elfutils/src/strip.c
1500     @@ -565,6 +565,11 @@ handle_elf (int fd, Elf *elf, const char
1501     goto fail_close;
1502     }
1503    
1504     + if (shstrndx >= shnum)
1505     + goto illformed;
1506     +
1507     +#define elf_assert(test) do { if (!(test)) goto illformed; } while (0)
1508     +
1509     /* Storage for section information. We leave room for two more
1510     entries since we unconditionally create a section header string
1511     table. Maybe some weird tool created an ELF file without one.
1512     @@ -586,7 +591,7 @@ handle_elf (int fd, Elf *elf, const char
1513     {
1514     /* This should always be true (i.e., there should not be any
1515     holes in the numbering). */
1516     - assert (elf_ndxscn (scn) == cnt);
1517     + elf_assert (elf_ndxscn (scn) == cnt);
1518    
1519     shdr_info[cnt].scn = scn;
1520    
1521     @@ -599,6 +604,7 @@ handle_elf (int fd, Elf *elf, const char
1522     shdr_info[cnt].shdr.sh_name);
1523     if (shdr_info[cnt].name == NULL)
1524     {
1525     + illformed:
1526     error (0, 0, gettext ("illformed file '%s'"), fname);
1527     goto fail_close;
1528     }
1529     @@ -608,6 +614,8 @@ handle_elf (int fd, Elf *elf, const char
1530    
1531     /* Remember the shdr.sh_link value. */
1532     shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
1533     + if (shdr_info[cnt].old_sh_link >= shnum)
1534     + goto illformed;
1535    
1536     /* Sections in files other than relocatable object files which
1537     are not loaded can be freely moved by us. In relocatable
1538     @@ -620,7 +628,7 @@ handle_elf (int fd, Elf *elf, const char
1539     appropriate reference. */
1540     if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
1541     {
1542     - assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
1543     + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
1544     shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
1545     }
1546     else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
1547     @@ -637,7 +645,12 @@ handle_elf (int fd, Elf *elf, const char
1548     for (inner = 1;
1549     inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1550     ++inner)
1551     + {
1552     + if (grpref[inner] < shnum)
1553     shdr_info[grpref[inner]].group_idx = cnt;
1554     + else
1555     + goto illformed;
1556     + }
1557    
1558     if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
1559     /* If the section group contains only one element and this
1560     @@ -648,7 +661,7 @@ handle_elf (int fd, Elf *elf, const char
1561     }
1562     else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
1563     {
1564     - assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
1565     + elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
1566     shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
1567     }
1568    
1569     @@ -656,7 +669,7 @@ handle_elf (int fd, Elf *elf, const char
1570     discarded right away. */
1571     if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
1572     {
1573     - assert (shdr_info[cnt].group_idx != 0);
1574     + elf_assert (shdr_info[cnt].group_idx != 0);
1575    
1576     if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
1577     {
1578     @@ -732,10 +745,14 @@ handle_elf (int fd, Elf *elf, const char
1579     {
1580     /* If a relocation section is marked as being removed make
1581     sure the section it is relocating is removed, too. */
1582     - if ((shdr_info[cnt].shdr.sh_type == SHT_REL
1583     + if (shdr_info[cnt].shdr.sh_type == SHT_REL
1584     || shdr_info[cnt].shdr.sh_type == SHT_RELA)
1585     - && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
1586     - shdr_info[cnt].idx = 1;
1587     + {
1588     + if (shdr_info[cnt].shdr.sh_info >= shnum)
1589     + goto illformed;
1590     + else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
1591     + shdr_info[cnt].idx = 1;
1592     + }
1593    
1594     /* If a group section is marked as being removed make
1595     sure all the sections it contains are being removed, too. */
1596     @@ -779,7 +796,7 @@ handle_elf (int fd, Elf *elf, const char
1597     if (shdr_info[cnt].symtab_idx != 0
1598     && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
1599     {
1600     - assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
1601     + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
1602    
1603     shdr_info[shdr_info[cnt].symtab_idx].data
1604     = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1605     @@ -819,6 +836,9 @@ handle_elf (int fd, Elf *elf, const char
1606     else if (scnidx == SHN_XINDEX)
1607     scnidx = xndx;
1608    
1609     + if (scnidx >= shnum)
1610     + goto illformed;
1611     +
1612     if (shdr_info[scnidx].idx == 0)
1613     /* This symbol table has a real symbol in
1614     a discarded section. So preserve the
1615     @@ -849,12 +869,16 @@ handle_elf (int fd, Elf *elf, const char
1616     }
1617    
1618     /* Handle references through sh_info. */
1619     - if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
1620     - && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
1621     + if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1622     + {
1623     + if (shdr_info[cnt].shdr.sh_info >= shnum)
1624     + goto illformed;
1625     + else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
1626     {
1627     shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
1628     changes |= shdr_info[cnt].shdr.sh_info < cnt;
1629     }
1630     + }
1631    
1632     /* Mark the section as investigated. */
1633     shdr_info[cnt].idx = 2;
1634     @@ -995,7 +1019,7 @@ handle_elf (int fd, Elf *elf, const char
1635     error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
1636     elf_errmsg (-1));
1637    
1638     - assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1639     + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1640    
1641     /* Add this name to the section header string table. */
1642     shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
1643     @@ -1032,7 +1056,7 @@ handle_elf (int fd, Elf *elf, const char
1644     error (EXIT_FAILURE, 0,
1645     gettext ("while create section header section: %s"),
1646     elf_errmsg (-1));
1647     - assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1648     + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1649    
1650     shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
1651     if (shdr_info[cnt].data == NULL)
1652     @@ -1089,7 +1113,7 @@ handle_elf (int fd, Elf *elf, const char
1653     error (EXIT_FAILURE, 0,
1654     gettext ("while create section header section: %s"),
1655     elf_errmsg (-1));
1656     - assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1657     + elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1658    
1659     /* Finalize the string table and fill in the correct indices in the
1660     section headers. */
1661     @@ -1179,20 +1203,20 @@ handle_elf (int fd, Elf *elf, const char
1662     shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1663     NULL);
1664    
1665     - assert ((versiondata->d_size / sizeof (Elf32_Word))
1666     + elf_assert ((versiondata->d_size / sizeof (Elf32_Word))
1667     >= shdr_info[cnt].data->d_size / elsize);
1668     }
1669    
1670     if (shdr_info[cnt].version_idx != 0)
1671     {
1672     - assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1673     + elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1674     /* This section has associated version
1675     information. We have to modify that
1676     information, too. */
1677     versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1678     NULL);
1679    
1680     - assert ((versiondata->d_size / sizeof (GElf_Versym))
1681     + elf_assert ((versiondata->d_size / sizeof (GElf_Versym))
1682     >= shdr_info[cnt].data->d_size / elsize);
1683     }
1684    
1685     @@ -1247,7 +1271,7 @@ handle_elf (int fd, Elf *elf, const char
1686     sec = shdr_info[sym->st_shndx].idx;
1687     else
1688     {
1689     - assert (shndxdata != NULL);
1690     + elf_assert (shndxdata != NULL);
1691    
1692     sec = shdr_info[xshndx].idx;
1693     }
1694     @@ -1268,7 +1292,7 @@ handle_elf (int fd, Elf *elf, const char
1695     nxshndx = sec;
1696     }
1697    
1698     - assert (sec < SHN_LORESERVE || shndxdata != NULL);
1699     + elf_assert (sec < SHN_LORESERVE || shndxdata != NULL);
1700    
1701     if ((inner != destidx || nshndx != sym->st_shndx
1702     || (shndxdata != NULL && nxshndx != xshndx))
1703     @@ -1295,9 +1319,11 @@ handle_elf (int fd, Elf *elf, const char
1704     {
1705     size_t sidx = (sym->st_shndx != SHN_XINDEX
1706     ? sym->st_shndx : xshndx);
1707     - assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
1708     - || (shdr_info[sidx].shdr.sh_type == SHT_GROUP
1709     - && shdr_info[sidx].shdr.sh_info == inner));
1710     + elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
1711     + || ((shdr_info[sidx].shdr.sh_type
1712     + == SHT_GROUP)
1713     + && (shdr_info[sidx].shdr.sh_info
1714     + == inner)));
1715     }
1716     }
1717    
1718     @@ -1485,11 +1511,11 @@ handle_elf (int fd, Elf *elf, const char
1719     {
1720     GElf_Sym sym_mem;
1721     GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1722     - assert (sym != NULL);
1723     + elf_assert (sym != NULL);
1724    
1725     const char *name = elf_strptr (elf, strshndx,
1726     sym->st_name);
1727     - assert (name != NULL);
1728     + elf_assert (name != NULL);
1729     size_t hidx = elf_hash (name) % nbucket;
1730    
1731     if (bucket[hidx] == 0)
1732     @@ -1508,8 +1534,8 @@ handle_elf (int fd, Elf *elf, const char
1733     else
1734     {
1735     /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
1736     - assert (shdr_info[cnt].shdr.sh_entsize
1737     - == sizeof (Elf64_Xword));
1738     + elf_assert (shdr_info[cnt].shdr.sh_entsize
1739     + == sizeof (Elf64_Xword));
1740    
1741     Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1742    
1743     @@ -1539,11 +1565,11 @@ handle_elf (int fd, Elf *elf, const char
1744     {
1745     GElf_Sym sym_mem;
1746     GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1747     - assert (sym != NULL);
1748     + elf_assert (sym != NULL);
1749    
1750     const char *name = elf_strptr (elf, strshndx,
1751     sym->st_name);
1752     - assert (name != NULL);
1753     + elf_assert (name != NULL);
1754     size_t hidx = elf_hash (name) % nbucket;
1755    
1756     if (bucket[hidx] == 0)