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