- up to 0.157
[packages/elfutils.git] / elfutils-robustify.patch
1 --- elfutils/libdwfl/ChangeLog
2 +++ elfutils/libdwfl/ChangeLog
3 @@ -256,6 +256,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 @@ -715,10 +715,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 @@ -504,6 +504,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 @@ -2216,6 +2222,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 @@ -2261,6 +2277,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 @@ -1363,6 +1363,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 @@ -1375,8 +1377,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 @@ -1527,10 +1529,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 @@ -1542,21 +1546,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 @@ -1705,7 +1714,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 @@ -1891,7 +1901,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 @@ -2138,6 +2149,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 @@ -2148,15 +2166,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 @@ -2392,7 +2407,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 @@ -2403,9 +2424,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 @@ -2458,8 +2477,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 @@ -2471,9 +2496,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 @@ -2735,25 +2758,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 @@ -2802,7 +2830,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 @@ -2815,9 +2853,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 @@ -3077,7 +3113,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 @@ -4397,6 +4434,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)
This page took 0.242043 seconds and 3 git commands to generate.