Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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