]>
Commit | Line | Data |
---|---|---|
52cb69e7 AM |
1 | 2005-06-09 Jakub Jelinek <jakub@redhat.com> |
2 | ||
3 | * readelf.c (cmalloc, xcmalloc, xcrealloc): New functions. | |
4 | (get_data): Add nmemb argument. Return NULL if nmemb * size | |
5 | overflows. If var == NULL, allocate one extra byte and | |
6 | clear it. | |
7 | (slurp_rela_relocs, slurp_rel_relocs, get_32bit_program_headers, | |
8 | get_64bit_program_headers, get_program_headers, | |
9 | get_32bit_section_headers, get_64bit_section_headers, | |
10 | get_32bit_elf_symbols, get_64bit_elf_symbols, process_section_headers, | |
11 | process_section_groups, process_relocs, slurp_ia64_unwind_table, | |
12 | ia64_process_unwind, slurp_hppa_unwind_table, hppa_process_unwind, | |
13 | get_32bit_dynamic_section, get_64bit_dynamic_section, | |
14 | process_dynamic_section, process_version_sections, get_dynamic_data, | |
15 | process_symbol_table, dump_section, load_debug_str, load_debug_loc, | |
16 | load_debug_range, get_debug_info, frame_need_space, | |
17 | display_debug_frames, display_debug_section, process_mips_specific, | |
18 | process_gnu_liblist, process_corefile_note_segment): Adjust get_data | |
19 | callers. Use cmalloc, xcmalloc and xcrealloc instead of | |
20 | {m,xm,xre}alloc where passed size is a product of 2 numbers. | |
21 | ||
22 | * readelf.c (print_mode): Fix comment typo. | |
23 | (slurp_rela_relocs, slurp_rel_relocs): Fix memory leaks. | |
24 | (dump_relocations): Fix a thinko in check for invalid st_name. | |
25 | (process_program_headers): Don't crash if string_table is NULL. | |
26 | (process_section_headers): Don't crash if e_shstrndx is invalid. | |
27 | Ensure string_table_length is 0 if string_table == NULL. | |
28 | Don't return just because string_table is NULL. | |
29 | (process_section_groups): Don't crash if symtab's sh_link or | |
30 | symbol's st_name is invalid. Fix a memory leak. Fix check for | |
31 | invalid section number entry. | |
32 | (process_relocs): Don't crash if relocation or symbol section's | |
33 | sh_link is invalid. | |
34 | (slurp_ia64_unwind_table, slurp_hppa_unwind_table): Don't crash if | |
35 | relocation section's sh_info is invalid. | |
36 | (ia64_process_unwind, hppa_process_unwind): Don't crash if symbol | |
37 | table's sh_link is invalid. | |
38 | (process_version_sections): Don't crash on version or symbol | |
39 | section's sh_link is invalid. Don't crash if symbol's st_shndx | |
40 | is invalid. | |
41 | (process_symbol_table): Don't crash if string table is corrupt | |
42 | or symbol's st_name, st_shndx, vna_name or vda_name is invalid. | |
43 | (debug_apply_rela_addends): Don't crash if relocation section's | |
44 | sh_info or sh_link is invalid. | |
45 | (process_gnu_liblist): Don't crash if liblist section's sh_link | |
46 | or entry's l_name is invalid. | |
47 | ||
48 | 2005-05-24 H.J. Lu <hongjiu.lu@intel.com> | |
49 | ||
50 | * readelf.c (process_section_groups): Check if the section member | |
51 | index is valid. | |
52 | ||
53 | --- binutils/readelf.c.jj 2005-06-09 10:58:53.000000000 +0200 | |
54 | +++ binutils/readelf.c 2005-06-09 14:29:23.000000000 +0200 | |
55 | @@ -203,7 +203,7 @@ unsigned int num_dump_sects = 0; | |
56 | #define DISASS_DUMP (1 << 1) | |
57 | #define DEBUG_DUMP (1 << 2) | |
58 | ||
59 | -/* How to rpint a vma value. */ | |
60 | +/* How to print a vma value. */ | |
61 | typedef enum print_mode | |
62 | { | |
63 | HEX, | |
64 | @@ -297,11 +297,42 @@ warn (const char *message, ...) | |
65 | } | |
66 | ||
67 | static void * | |
68 | -get_data (void *var, FILE *file, long offset, size_t size, const char *reason) | |
69 | +cmalloc (size_t nmemb, size_t size) | |
70 | +{ | |
71 | + /* Check for overflow. */ | |
72 | + if (nmemb >= ~(size_t) 0 / size) | |
73 | + return NULL; | |
74 | + else | |
75 | + return malloc (nmemb * size); | |
76 | +} | |
77 | + | |
78 | +static void * | |
79 | +xcmalloc (size_t nmemb, size_t size) | |
80 | +{ | |
81 | + /* Check for overflow. */ | |
82 | + if (nmemb >= ~(size_t) 0 / size) | |
83 | + return NULL; | |
84 | + else | |
85 | + return xmalloc (nmemb * size); | |
86 | +} | |
87 | + | |
88 | +static void * | |
89 | +xcrealloc (void *ptr, size_t nmemb, size_t size) | |
90 | +{ | |
91 | + /* Check for overflow. */ | |
92 | + if (nmemb >= ~(size_t) 0 / size) | |
93 | + return NULL; | |
94 | + else | |
95 | + return xrealloc (ptr, nmemb * size); | |
96 | +} | |
97 | + | |
98 | +static void * | |
99 | +get_data (void *var, FILE *file, long offset, size_t size, size_t nmemb, | |
100 | + const char *reason) | |
101 | { | |
102 | void *mvar; | |
103 | ||
104 | - if (size == 0) | |
105 | + if (size == 0 || nmemb == 0) | |
106 | return NULL; | |
107 | ||
108 | if (fseek (file, archive_file_offset + offset, SEEK_SET)) | |
109 | @@ -314,19 +345,24 @@ get_data (void *var, FILE *file, long of | |
110 | mvar = var; | |
111 | if (mvar == NULL) | |
112 | { | |
113 | - mvar = malloc (size); | |
114 | + /* Check for overflow. */ | |
115 | + if (nmemb < (~(size_t) 0 - 1) / size) | |
116 | + /* + 1 so that we can '\0' terminate invalid string table sections. */ | |
117 | + mvar = malloc (size * nmemb + 1); | |
118 | ||
119 | if (mvar == NULL) | |
120 | { | |
121 | error (_("Out of memory allocating 0x%x bytes for %s\n"), | |
122 | - size, reason); | |
123 | + size * nmemb, reason); | |
124 | return NULL; | |
125 | } | |
126 | + | |
127 | + ((char *) mvar)[size * nmemb] = '\0'; | |
128 | } | |
129 | ||
130 | - if (fread (mvar, size, 1, file) != 1) | |
131 | + if (fread (mvar, size, nmemb, file) != nmemb) | |
132 | { | |
133 | - error (_("Unable to read in 0x%x bytes of %s\n"), size, reason); | |
134 | + error (_("Unable to read in 0x%x bytes of %s\n"), size * nmemb, reason); | |
135 | if (mvar != var) | |
136 | free (mvar); | |
137 | return NULL; | |
138 | @@ -747,16 +783,17 @@ slurp_rela_relocs (FILE *file, | |
139 | { | |
140 | Elf32_External_Rela *erelas; | |
141 | ||
142 | - erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs")); | |
143 | + erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs")); | |
144 | if (!erelas) | |
145 | return 0; | |
146 | ||
147 | nrelas = rel_size / sizeof (Elf32_External_Rela); | |
148 | ||
149 | - relas = malloc (nrelas * sizeof (Elf_Internal_Rela)); | |
150 | + relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela)); | |
151 | ||
152 | if (relas == NULL) | |
153 | { | |
154 | + free (erelas); | |
155 | error (_("out of memory parsing relocs")); | |
156 | return 0; | |
157 | } | |
158 | @@ -774,16 +811,17 @@ slurp_rela_relocs (FILE *file, | |
159 | { | |
160 | Elf64_External_Rela *erelas; | |
161 | ||
162 | - erelas = get_data (NULL, file, rel_offset, rel_size, _("relocs")); | |
163 | + erelas = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs")); | |
164 | if (!erelas) | |
165 | return 0; | |
166 | ||
167 | nrelas = rel_size / sizeof (Elf64_External_Rela); | |
168 | ||
169 | - relas = malloc (nrelas * sizeof (Elf_Internal_Rela)); | |
170 | + relas = cmalloc (nrelas, sizeof (Elf_Internal_Rela)); | |
171 | ||
172 | if (relas == NULL) | |
173 | { | |
174 | + free (erelas); | |
175 | error (_("out of memory parsing relocs")); | |
176 | return 0; | |
177 | } | |
178 | @@ -817,16 +855,17 @@ slurp_rel_relocs (FILE *file, | |
179 | { | |
180 | Elf32_External_Rel *erels; | |
181 | ||
182 | - erels = get_data (NULL, file, rel_offset, rel_size, _("relocs")); | |
183 | + erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs")); | |
184 | if (!erels) | |
185 | return 0; | |
186 | ||
187 | nrels = rel_size / sizeof (Elf32_External_Rel); | |
188 | ||
189 | - rels = malloc (nrels * sizeof (Elf_Internal_Rela)); | |
190 | + rels = cmalloc (nrels, sizeof (Elf_Internal_Rela)); | |
191 | ||
192 | if (rels == NULL) | |
193 | { | |
194 | + free (erels); | |
195 | error (_("out of memory parsing relocs")); | |
196 | return 0; | |
197 | } | |
198 | @@ -844,16 +883,17 @@ slurp_rel_relocs (FILE *file, | |
199 | { | |
200 | Elf64_External_Rel *erels; | |
201 | ||
202 | - erels = get_data (NULL, file, rel_offset, rel_size, _("relocs")); | |
203 | + erels = get_data (NULL, file, rel_offset, 1, rel_size, _("relocs")); | |
204 | if (!erels) | |
205 | return 0; | |
206 | ||
207 | nrels = rel_size / sizeof (Elf64_External_Rel); | |
208 | ||
209 | - rels = malloc (nrels * sizeof (Elf_Internal_Rela)); | |
210 | + rels = cmalloc (nrels, sizeof (Elf_Internal_Rela)); | |
211 | ||
212 | if (rels == NULL) | |
213 | { | |
214 | + free (erels); | |
215 | error (_("out of memory parsing relocs")); | |
216 | return 0; | |
217 | } | |
218 | @@ -1271,7 +1311,7 @@ dump_relocations (FILE *file, | |
219 | } | |
220 | else if (strtab == NULL) | |
221 | printf (_("<string table index: %3ld>"), psym->st_name); | |
222 | - else if (psym->st_name > strtablen) | |
223 | + else if (psym->st_name >= strtablen) | |
224 | printf (_("<corrupt string table index: %3ld>"), psym->st_name); | |
225 | else | |
226 | print_symbol (22, strtab + psym->st_name); | |
227 | @@ -3047,7 +3087,7 @@ get_32bit_program_headers (FILE *file, E | |
228 | unsigned int i; | |
229 | ||
230 | phdrs = get_data (NULL, file, elf_header.e_phoff, | |
231 | - elf_header.e_phentsize * elf_header.e_phnum, | |
232 | + elf_header.e_phentsize, elf_header.e_phnum, | |
233 | _("program headers")); | |
234 | if (!phdrs) | |
235 | return 0; | |
236 | @@ -3080,7 +3120,7 @@ get_64bit_program_headers (FILE *file, E | |
237 | unsigned int i; | |
238 | ||
239 | phdrs = get_data (NULL, file, elf_header.e_phoff, | |
240 | - elf_header.e_phentsize * elf_header.e_phnum, | |
241 | + elf_header.e_phentsize, elf_header.e_phnum, | |
242 | _("program headers")); | |
243 | if (!phdrs) | |
244 | return 0; | |
245 | @@ -3115,7 +3155,7 @@ get_program_headers (FILE *file) | |
246 | if (program_headers != NULL) | |
247 | return 1; | |
248 | ||
249 | - phdrs = malloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr)); | |
250 | + phdrs = cmalloc (elf_header.e_phnum, sizeof (Elf_Internal_Phdr)); | |
251 | ||
252 | if (phdrs == NULL) | |
253 | { | |
254 | @@ -3334,13 +3374,11 @@ process_program_headers (FILE *file) | |
255 | putc ('\n', stdout); | |
256 | } | |
257 | ||
258 | - if (do_segments && section_headers != NULL) | |
259 | + if (do_segments && section_headers != NULL && string_table != NULL) | |
260 | { | |
261 | printf (_("\n Section to Segment mapping:\n")); | |
262 | printf (_(" Segment Sections...\n")); | |
263 | ||
264 | - assert (string_table != NULL); | |
265 | - | |
266 | for (i = 0; i < elf_header.e_phnum; i++) | |
267 | { | |
268 | unsigned int j; | |
269 | @@ -3418,11 +3456,11 @@ get_32bit_section_headers (FILE *file, u | |
270 | unsigned int i; | |
271 | ||
272 | shdrs = get_data (NULL, file, elf_header.e_shoff, | |
273 | - elf_header.e_shentsize * num, _("section headers")); | |
274 | + elf_header.e_shentsize, num, _("section headers")); | |
275 | if (!shdrs) | |
276 | return 0; | |
277 | ||
278 | - section_headers = malloc (num * sizeof (Elf_Internal_Shdr)); | |
279 | + section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr)); | |
280 | ||
281 | if (section_headers == NULL) | |
282 | { | |
283 | @@ -3459,11 +3497,11 @@ get_64bit_section_headers (FILE *file, u | |
284 | unsigned int i; | |
285 | ||
286 | shdrs = get_data (NULL, file, elf_header.e_shoff, | |
287 | - elf_header.e_shentsize * num, _("section headers")); | |
288 | + elf_header.e_shentsize, num, _("section headers")); | |
289 | if (!shdrs) | |
290 | return 0; | |
291 | ||
292 | - section_headers = malloc (num * sizeof (Elf_Internal_Shdr)); | |
293 | + section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr)); | |
294 | ||
295 | if (section_headers == NULL) | |
296 | { | |
297 | @@ -3502,7 +3540,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I | |
298 | Elf_Internal_Sym *psym; | |
299 | unsigned int j; | |
300 | ||
301 | - esyms = get_data (NULL, file, section->sh_offset, section->sh_size, | |
302 | + esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size, | |
303 | _("symbols")); | |
304 | if (!esyms) | |
305 | return NULL; | |
306 | @@ -3513,7 +3551,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I | |
307 | == (unsigned long) SECTION_HEADER_NUM (section - section_headers))) | |
308 | { | |
309 | shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset, | |
310 | - symtab_shndx_hdr->sh_size, _("symtab shndx")); | |
311 | + 1, symtab_shndx_hdr->sh_size, _("symtab shndx")); | |
312 | if (!shndx) | |
313 | { | |
314 | free (esyms); | |
315 | @@ -3522,7 +3560,7 @@ get_32bit_elf_symbols (FILE *file, Elf_I | |
316 | } | |
317 | ||
318 | number = section->sh_size / section->sh_entsize; | |
319 | - isyms = malloc (number * sizeof (Elf_Internal_Sym)); | |
320 | + isyms = cmalloc (number, sizeof (Elf_Internal_Sym)); | |
321 | ||
322 | if (isyms == NULL) | |
323 | { | |
324 | @@ -3565,7 +3603,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I | |
325 | Elf_Internal_Sym *psym; | |
326 | unsigned int j; | |
327 | ||
328 | - esyms = get_data (NULL, file, section->sh_offset, section->sh_size, | |
329 | + esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size, | |
330 | _("symbols")); | |
331 | if (!esyms) | |
332 | return NULL; | |
333 | @@ -3576,7 +3614,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I | |
334 | == (unsigned long) SECTION_HEADER_NUM (section - section_headers))) | |
335 | { | |
336 | shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset, | |
337 | - symtab_shndx_hdr->sh_size, _("symtab shndx")); | |
338 | + 1, symtab_shndx_hdr->sh_size, _("symtab shndx")); | |
339 | if (!shndx) | |
340 | { | |
341 | free (esyms); | |
342 | @@ -3585,7 +3623,7 @@ get_64bit_elf_symbols (FILE *file, Elf_I | |
343 | } | |
344 | ||
345 | number = section->sh_size / section->sh_entsize; | |
346 | - isyms = malloc (number * sizeof (Elf_Internal_Sym)); | |
347 | + isyms = cmalloc (number, sizeof (Elf_Internal_Sym)); | |
348 | ||
349 | if (isyms == NULL) | |
350 | { | |
351 | @@ -3694,17 +3732,17 @@ process_section_headers (FILE *file) | |
352 | return 0; | |
353 | ||
354 | /* Read in the string table, so that we have names to display. */ | |
355 | - section = SECTION_HEADER (elf_header.e_shstrndx); | |
356 | - | |
357 | - if (section->sh_size != 0) | |
358 | + if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum) | |
359 | { | |
360 | - string_table = get_data (NULL, file, section->sh_offset, | |
361 | - section->sh_size, _("string table")); | |
362 | + section = SECTION_HEADER (elf_header.e_shstrndx); | |
363 | ||
364 | - if (string_table == NULL) | |
365 | - return 0; | |
366 | + if (section->sh_size != 0) | |
367 | + { | |
368 | + string_table = get_data (NULL, file, section->sh_offset, | |
369 | + 1, section->sh_size, _("string table")); | |
370 | ||
371 | - string_table_length = section->sh_size; | |
372 | + string_table_length = string_table != NULL ? section->sh_size : 0; | |
373 | + } | |
374 | } | |
375 | ||
376 | /* Scan the sections for the dynamic symbol table | |
377 | @@ -3741,7 +3779,7 @@ process_section_headers (FILE *file) | |
378 | } | |
379 | ||
380 | dynamic_strings = get_data (NULL, file, section->sh_offset, | |
381 | - section->sh_size, _("dynamic strings")); | |
382 | + 1, section->sh_size, _("dynamic strings")); | |
383 | dynamic_strings_length = section->sh_size; | |
384 | } | |
385 | else if (section->sh_type == SHT_SYMTAB_SHNDX) | |
386 | @@ -3928,6 +3966,7 @@ process_section_groups (FILE *file) | |
387 | Elf_Internal_Shdr *symtab_sec, *strtab_sec; | |
388 | Elf_Internal_Sym *symtab; | |
389 | char *strtab; | |
390 | + size_t strtab_size; | |
391 | ||
392 | /* Don't process section groups unless needed. */ | |
393 | if (!do_unwind && !do_section_groups) | |
394 | @@ -3984,6 +4023,7 @@ process_section_groups (FILE *file) | |
395 | strtab_sec = NULL; | |
396 | symtab = NULL; | |
397 | strtab = NULL; | |
398 | + strtab_size = 0; | |
399 | for (i = 0, section = section_headers, group = section_groups; | |
400 | i < elf_header.e_shnum; | |
401 | i++, section++) | |
402 | @@ -3997,8 +4037,9 @@ process_section_groups (FILE *file) | |
403 | Elf_Internal_Sym *sym; | |
404 | ||
405 | /* Get the symbol table. */ | |
406 | - sec = SECTION_HEADER (section->sh_link); | |
407 | - if (sec->sh_type != SHT_SYMTAB) | |
408 | + if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum | |
409 | + || ((sec = SECTION_HEADER (section->sh_link))->sh_type | |
410 | + != SHT_SYMTAB)) | |
411 | { | |
412 | error (_("Bad sh_link in group section `%s'\n"), name); | |
413 | continue; | |
414 | @@ -4024,26 +4065,41 @@ process_section_groups (FILE *file) | |
415 | } | |
416 | ||
417 | group_name = SECTION_NAME (section_headers + sec_index); | |
418 | + strtab_sec = NULL; | |
419 | + if (strtab) | |
420 | + free (strtab); | |
421 | strtab = NULL; | |
422 | + strtab_size = 0; | |
423 | } | |
424 | else | |
425 | { | |
426 | /* Get the string table. */ | |
427 | - sec = SECTION_HEADER (symtab_sec->sh_link); | |
428 | - if (strtab_sec != sec) | |
429 | + if (SECTION_HEADER_INDEX (symtab_sec->sh_link) | |
430 | + >= elf_header.e_shnum) | |
431 | + { | |
432 | + strtab_sec = NULL; | |
433 | + if (strtab) | |
434 | + free (strtab); | |
435 | + strtab = NULL; | |
436 | + strtab_size = 0; | |
437 | + } | |
438 | + else if (strtab_sec | |
439 | + != (sec = SECTION_HEADER (symtab_sec->sh_link))) | |
440 | { | |
441 | strtab_sec = sec; | |
442 | if (strtab) | |
443 | free (strtab); | |
444 | strtab = get_data (NULL, file, strtab_sec->sh_offset, | |
445 | - strtab_sec->sh_size, | |
446 | + 1, strtab_sec->sh_size, | |
447 | _("string table")); | |
448 | + strtab_size = strtab != NULL ? strtab_sec->sh_size : 0; | |
449 | } | |
450 | - group_name = strtab + sym->st_name; | |
451 | + group_name = sym->st_name < strtab_size | |
452 | + ? strtab + sym->st_name : "<corrupt>"; | |
453 | } | |
454 | ||
455 | start = get_data (NULL, file, section->sh_offset, | |
456 | - section->sh_size, _("section data")); | |
457 | + 1, section->sh_size, _("section data")); | |
458 | ||
459 | indices = start; | |
460 | size = (section->sh_size / section->sh_entsize) - 1; | |
461 | @@ -4067,6 +4123,19 @@ process_section_groups (FILE *file) | |
462 | entry = byte_get (indices, 4); | |
463 | indices += 4; | |
464 | ||
465 | + if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum) | |
466 | + { | |
467 | + error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"), | |
468 | + entry, i, elf_header.e_shnum - 1); | |
469 | + continue; | |
470 | + } | |
471 | + else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE) | |
472 | + { | |
473 | + error (_("invalid section [%5u] in group section [%5u]\n"), | |
474 | + entry, i); | |
475 | + continue; | |
476 | + } | |
477 | + | |
478 | if (section_headers_groups [SECTION_HEADER_INDEX (entry)] | |
479 | != NULL) | |
480 | { | |
481 | @@ -4098,8 +4167,7 @@ process_section_groups (FILE *file) | |
482 | if (do_section_groups) | |
483 | { | |
484 | sec = SECTION_HEADER (entry); | |
485 | - printf (" [%5u] %s\n", | |
486 | - entry, SECTION_NAME (sec)); | |
487 | + printf (" [%5u] %s\n", entry, SECTION_NAME (sec)); | |
488 | } | |
489 | ||
490 | g = xmalloc (sizeof (struct group_list)); | |
491 | @@ -4230,12 +4298,14 @@ process_relocs (FILE *file) | |
492 | ||
493 | is_rela = section->sh_type == SHT_RELA; | |
494 | ||
495 | - if (section->sh_link) | |
496 | + if (section->sh_link | |
497 | + && SECTION_HEADER_INDEX (section->sh_link) | |
498 | + < elf_header.e_shnum) | |
499 | { | |
500 | Elf_Internal_Shdr *symsec; | |
501 | Elf_Internal_Sym *symtab; | |
502 | unsigned long nsyms; | |
503 | - unsigned long strtablen; | |
504 | + unsigned long strtablen = 0; | |
505 | char *strtab = NULL; | |
506 | ||
507 | symsec = SECTION_HEADER (section->sh_link); | |
508 | @@ -4245,11 +4315,16 @@ process_relocs (FILE *file) | |
509 | if (symtab == NULL) | |
510 | continue; | |
511 | ||
512 | - strsec = SECTION_HEADER (symsec->sh_link); | |
513 | + if (SECTION_HEADER_INDEX (symsec->sh_link) | |
514 | + < elf_header.e_shnum) | |
515 | + { | |
516 | + strsec = SECTION_HEADER (symsec->sh_link); | |
517 | ||
518 | - strtab = get_data (NULL, file, strsec->sh_offset, | |
519 | - strsec->sh_size, _("string table")); | |
520 | - strtablen = strtab == NULL ? 0 : strsec->sh_size; | |
521 | + strtab = get_data (NULL, file, strsec->sh_offset, | |
522 | + 1, strsec->sh_size, | |
523 | + _("string table")); | |
524 | + strtablen = strtab == NULL ? 0 : strsec->sh_size; | |
525 | + } | |
526 | ||
527 | dump_relocations (file, rel_offset, rel_size, | |
528 | symtab, nsyms, strtab, strtablen, is_rela); | |
529 | @@ -4445,11 +4520,11 @@ slurp_ia64_unwind_table (FILE *file, | |
530 | ||
531 | /* Second, build the unwind table from the contents of the unwind section: */ | |
532 | size = sec->sh_size; | |
533 | - table = get_data (NULL, file, sec->sh_offset, size, _("unwind table")); | |
534 | + table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table")); | |
535 | if (!table) | |
536 | return 0; | |
537 | ||
538 | - tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0])); | |
539 | + tep = aux->table = xcmalloc (size / (3 * addr_size), sizeof (aux->table[0])); | |
540 | for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep) | |
541 | { | |
542 | tep->start.section = SHN_UNDEF; | |
543 | @@ -4480,6 +4555,7 @@ slurp_ia64_unwind_table (FILE *file, | |
544 | ++relsec) | |
545 | { | |
546 | if (relsec->sh_type != SHT_RELA | |
547 | + || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum | |
548 | || SECTION_HEADER (relsec->sh_info) != sec) | |
549 | continue; | |
550 | ||
551 | @@ -4547,15 +4623,16 @@ ia64_process_unwind (FILE *file) | |
552 | ||
553 | for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) | |
554 | { | |
555 | - if (sec->sh_type == SHT_SYMTAB) | |
556 | + if (sec->sh_type == SHT_SYMTAB | |
557 | + && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum) | |
558 | { | |
559 | aux.nsyms = sec->sh_size / sec->sh_entsize; | |
560 | aux.symtab = GET_ELF_SYMBOLS (file, sec); | |
561 | ||
562 | strsec = SECTION_HEADER (sec->sh_link); | |
563 | - aux.strtab_size = strsec->sh_size; | |
564 | aux.strtab = get_data (NULL, file, strsec->sh_offset, | |
565 | - aux.strtab_size, _("string table")); | |
566 | + 1, strsec->sh_size, _("string table")); | |
567 | + aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; | |
568 | } | |
569 | else if (sec->sh_type == SHT_IA_64_UNWIND) | |
570 | unwcount++; | |
571 | @@ -4636,7 +4713,7 @@ ia64_process_unwind (FILE *file) | |
572 | { | |
573 | aux.info_size = sec->sh_size; | |
574 | aux.info_addr = sec->sh_addr; | |
575 | - aux.info = get_data (NULL, file, sec->sh_offset, aux.info_size, | |
576 | + aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size, | |
577 | _("unwind info")); | |
578 | ||
579 | printf (_("\nUnwind section ")); | |
580 | @@ -4830,13 +4907,13 @@ slurp_hppa_unwind_table (FILE *file, | |
581 | /* Second, build the unwind table from the contents of the unwind | |
582 | section. */ | |
583 | size = sec->sh_size; | |
584 | - table = get_data (NULL, file, sec->sh_offset, size, _("unwind table")); | |
585 | + table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table")); | |
586 | if (!table) | |
587 | return 0; | |
588 | ||
589 | unw_ent_size = 2 * addr_size + 8; | |
590 | ||
591 | - tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0])); | |
592 | + tep = aux->table = xcmalloc (size / unw_ent_size, sizeof (aux->table[0])); | |
593 | ||
594 | for (tp = table; tp < table + size; tp += (2 * addr_size + 8), ++tep) | |
595 | { | |
596 | @@ -4904,6 +4981,7 @@ slurp_hppa_unwind_table (FILE *file, | |
597 | ++relsec) | |
598 | { | |
599 | if (relsec->sh_type != SHT_RELA | |
600 | + || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum | |
601 | || SECTION_HEADER (relsec->sh_info) != sec) | |
602 | continue; | |
603 | ||
604 | @@ -4968,20 +5046,23 @@ hppa_process_unwind (FILE *file) | |
605 | ||
606 | memset (& aux, 0, sizeof (aux)); | |
607 | ||
608 | - assert (string_table != NULL); | |
609 | + if (string_table == NULL) | |
610 | + return 1; | |
611 | + | |
612 | addr_size = is_32bit_elf ? 4 : 8; | |
613 | ||
614 | for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec) | |
615 | { | |
616 | - if (sec->sh_type == SHT_SYMTAB) | |
617 | + if (sec->sh_type == SHT_SYMTAB | |
618 | + && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum) | |
619 | { | |
620 | aux.nsyms = sec->sh_size / sec->sh_entsize; | |
621 | aux.symtab = GET_ELF_SYMBOLS (file, sec); | |
622 | ||
623 | strsec = SECTION_HEADER (sec->sh_link); | |
624 | - aux.strtab_size = strsec->sh_size; | |
625 | aux.strtab = get_data (NULL, file, strsec->sh_offset, | |
626 | - aux.strtab_size, _("string table")); | |
627 | + 1, strsec->sh_size, _("string table")); | |
628 | + aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0; | |
629 | } | |
630 | else if (streq (SECTION_NAME (sec), ".PARISC.unwind")) | |
631 | unwsec = sec; | |
632 | @@ -5197,7 +5278,7 @@ get_32bit_dynamic_section (FILE *file) | |
633 | Elf32_External_Dyn *edyn, *ext; | |
634 | Elf_Internal_Dyn *entry; | |
635 | ||
636 | - edyn = get_data (NULL, file, dynamic_addr, dynamic_size, | |
637 | + edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size, | |
638 | _("dynamic section")); | |
639 | if (!edyn) | |
640 | return 0; | |
641 | @@ -5214,7 +5295,7 @@ get_32bit_dynamic_section (FILE *file) | |
642 | break; | |
643 | } | |
644 | ||
645 | - dynamic_section = malloc (dynamic_nent * sizeof (*entry)); | |
646 | + dynamic_section = cmalloc (dynamic_nent, sizeof (*entry)); | |
647 | if (dynamic_section == NULL) | |
648 | { | |
649 | error (_("Out of memory\n")); | |
650 | @@ -5241,7 +5322,7 @@ get_64bit_dynamic_section (FILE *file) | |
651 | Elf64_External_Dyn *edyn, *ext; | |
652 | Elf_Internal_Dyn *entry; | |
653 | ||
654 | - edyn = get_data (NULL, file, dynamic_addr, dynamic_size, | |
655 | + edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size, | |
656 | _("dynamic section")); | |
657 | if (!edyn) | |
658 | return 0; | |
659 | @@ -5258,7 +5339,7 @@ get_64bit_dynamic_section (FILE *file) | |
660 | break; | |
661 | } | |
662 | ||
663 | - dynamic_section = malloc (dynamic_nent * sizeof (*entry)); | |
664 | + dynamic_section = cmalloc (dynamic_nent, sizeof (*entry)); | |
665 | if (dynamic_section == NULL) | |
666 | { | |
667 | error (_("Out of memory\n")); | |
668 | @@ -5418,7 +5499,7 @@ process_dynamic_section (FILE *file) | |
669 | continue; | |
670 | } | |
671 | ||
672 | - dynamic_strings = get_data (NULL, file, offset, str_tab_len, | |
673 | + dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len, | |
674 | _("dynamic string table")); | |
675 | dynamic_strings_length = str_tab_len; | |
676 | break; | |
677 | @@ -5453,8 +5534,8 @@ process_dynamic_section (FILE *file) | |
678 | Elf_Internal_Syminfo *syminfo; | |
679 | ||
680 | /* There is a syminfo section. Read the data. */ | |
681 | - extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, syminsz, | |
682 | - _("symbol information")); | |
683 | + extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1, | |
684 | + syminsz, _("symbol information")); | |
685 | if (!extsyminfo) | |
686 | return 0; | |
687 | ||
688 | @@ -5930,9 +6011,13 @@ process_version_sections (FILE *file) | |
689 | printf_vma (section->sh_addr); | |
690 | printf (_(" Offset: %#08lx Link: %lx (%s)\n"), | |
691 | (unsigned long) section->sh_offset, section->sh_link, | |
692 | - SECTION_NAME (SECTION_HEADER (section->sh_link))); | |
693 | + SECTION_HEADER_INDEX (section->sh_link) | |
694 | + < elf_header.e_shnum | |
695 | + ? SECTION_NAME (SECTION_HEADER (section->sh_link)) | |
696 | + : "<corrupt>"); | |
697 | ||
698 | - edefs = get_data (NULL, file, section->sh_offset, section->sh_size, | |
699 | + edefs = get_data (NULL, file, section->sh_offset, 1, | |
700 | + section->sh_size, | |
701 | _("version definition section")); | |
702 | if (!edefs) | |
703 | break; | |
704 | @@ -6019,9 +6104,13 @@ process_version_sections (FILE *file) | |
705 | printf_vma (section->sh_addr); | |
706 | printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"), | |
707 | (unsigned long) section->sh_offset, section->sh_link, | |
708 | - SECTION_NAME (SECTION_HEADER (section->sh_link))); | |
709 | + SECTION_HEADER_INDEX (section->sh_link) | |
710 | + < elf_header.e_shnum | |
711 | + ? SECTION_NAME (SECTION_HEADER (section->sh_link)) | |
712 | + : "<corrupt>"); | |
713 | ||
714 | - eneed = get_data (NULL, file, section->sh_offset, section->sh_size, | |
715 | + eneed = get_data (NULL, file, section->sh_offset, 1, | |
716 | + section->sh_size, | |
717 | _("version need section")); | |
718 | if (!eneed) | |
719 | break; | |
720 | @@ -6101,16 +6190,23 @@ process_version_sections (FILE *file) | |
721 | Elf_Internal_Shdr *string_sec; | |
722 | long off; | |
723 | ||
724 | + if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum) | |
725 | + break; | |
726 | + | |
727 | link_section = SECTION_HEADER (section->sh_link); | |
728 | total = section->sh_size / section->sh_entsize; | |
729 | ||
730 | + if (SECTION_HEADER_INDEX (link_section->sh_link) | |
731 | + >= elf_header.e_shnum) | |
732 | + break; | |
733 | + | |
734 | found = 1; | |
735 | ||
736 | symbols = GET_ELF_SYMBOLS (file, link_section); | |
737 | ||
738 | string_sec = SECTION_HEADER (link_section->sh_link); | |
739 | ||
740 | - strtab = get_data (NULL, file, string_sec->sh_offset, | |
741 | + strtab = get_data (NULL, file, string_sec->sh_offset, 1, | |
742 | string_sec->sh_size, _("version string table")); | |
743 | if (!strtab) | |
744 | break; | |
745 | @@ -6127,7 +6223,7 @@ process_version_sections (FILE *file) | |
746 | off = offset_from_vma (file, | |
747 | version_info[DT_VERSIONTAGIDX (DT_VERSYM)], | |
748 | total * sizeof (short)); | |
749 | - edata = get_data (NULL, file, off, total * sizeof (short), | |
750 | + edata = get_data (NULL, file, off, total, sizeof (short), | |
751 | _("version symbol data")); | |
752 | if (!edata) | |
753 | { | |
754 | @@ -6135,7 +6231,7 @@ process_version_sections (FILE *file) | |
755 | break; | |
756 | } | |
757 | ||
758 | - data = malloc (total * sizeof (short)); | |
759 | + data = cmalloc (total, sizeof (short)); | |
760 | ||
761 | for (cnt = total; cnt --;) | |
762 | data[cnt] = byte_get (edata + cnt * sizeof (short), | |
763 | @@ -6168,8 +6264,10 @@ process_version_sections (FILE *file) | |
764 | ||
765 | check_def = 1; | |
766 | check_need = 1; | |
767 | - if (SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type | |
768 | - != SHT_NOBITS) | |
769 | + if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx) | |
770 | + >= elf_header.e_shnum | |
771 | + || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type | |
772 | + != SHT_NOBITS) | |
773 | { | |
774 | if (symbols[cnt + j].st_shndx == SHN_UNDEF) | |
775 | check_def = 0; | |
776 | @@ -6194,7 +6292,7 @@ process_version_sections (FILE *file) | |
777 | Elf_External_Vernaux evna; | |
778 | unsigned long a_off; | |
779 | ||
780 | - get_data (&evn, file, offset, sizeof (evn), | |
781 | + get_data (&evn, file, offset, sizeof (evn), 1, | |
782 | _("version need")); | |
783 | ||
784 | ivn.vn_aux = BYTE_GET (evn.vn_aux); | |
785 | @@ -6205,7 +6303,7 @@ process_version_sections (FILE *file) | |
786 | do | |
787 | { | |
788 | get_data (&evna, file, a_off, sizeof (evna), | |
789 | - _("version need aux (2)")); | |
790 | + 1, _("version need aux (2)")); | |
791 | ||
792 | ivna.vna_next = BYTE_GET (evna.vna_next); | |
793 | ivna.vna_other = BYTE_GET (evna.vna_other); | |
794 | @@ -6246,7 +6344,7 @@ process_version_sections (FILE *file) | |
795 | ||
796 | do | |
797 | { | |
798 | - get_data (&evd, file, offset, sizeof (evd), | |
799 | + get_data (&evd, file, offset, sizeof (evd), 1, | |
800 | _("version def")); | |
801 | ||
802 | ivd.vd_next = BYTE_GET (evd.vd_next); | |
803 | @@ -6266,7 +6364,8 @@ process_version_sections (FILE *file) | |
804 | ||
805 | get_data (&evda, file, | |
806 | offset - ivd.vd_next + ivd.vd_aux, | |
807 | - sizeof (evda), _("version def aux")); | |
808 | + sizeof (evda), 1, | |
809 | + _("version def aux")); | |
810 | ||
811 | ivda.vda_name = BYTE_GET (evda.vda_name); | |
812 | ||
813 | @@ -6417,7 +6516,7 @@ get_dynamic_data (FILE *file, unsigned i | |
814 | unsigned char *e_data; | |
815 | int *i_data; | |
816 | ||
817 | - e_data = malloc (number * 4); | |
818 | + e_data = cmalloc (number, 4); | |
819 | ||
820 | if (e_data == NULL) | |
821 | { | |
822 | @@ -6431,7 +6530,7 @@ get_dynamic_data (FILE *file, unsigned i | |
823 | return NULL; | |
824 | } | |
825 | ||
826 | - i_data = malloc (number * sizeof (*i_data)); | |
827 | + i_data = cmalloc (number, sizeof (*i_data)); | |
828 | ||
829 | if (i_data == NULL) | |
830 | { | |
831 | @@ -6547,7 +6646,8 @@ process_symbol_table (FILE *file) | |
832 | i++, section++) | |
833 | { | |
834 | unsigned int si; | |
835 | - char *strtab; | |
836 | + char *strtab = NULL; | |
837 | + unsigned long int strtab_size = 0; | |
838 | Elf_Internal_Sym *symtab; | |
839 | Elf_Internal_Sym *psym; | |
840 | ||
841 | @@ -6569,15 +6669,19 @@ process_symbol_table (FILE *file) | |
842 | continue; | |
843 | ||
844 | if (section->sh_link == elf_header.e_shstrndx) | |
845 | - strtab = string_table; | |
846 | - else | |
847 | + { | |
848 | + strtab = string_table; | |
849 | + strtab_size = string_table_length; | |
850 | + } | |
851 | + else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum) | |
852 | { | |
853 | Elf_Internal_Shdr *string_sec; | |
854 | ||
855 | string_sec = SECTION_HEADER (section->sh_link); | |
856 | ||
857 | strtab = get_data (NULL, file, string_sec->sh_offset, | |
858 | - string_sec->sh_size, _("string table")); | |
859 | + 1, string_sec->sh_size, _("string table")); | |
860 | + strtab_size = strtab != NULL ? string_sec->sh_size : 0; | |
861 | } | |
862 | ||
863 | for (si = 0, psym = symtab; | |
864 | @@ -6592,7 +6696,8 @@ process_symbol_table (FILE *file) | |
865 | printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); | |
866 | printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); | |
867 | printf (" %4s ", get_symbol_index_type (psym->st_shndx)); | |
868 | - print_symbol (25, strtab + psym->st_name); | |
869 | + print_symbol (25, psym->st_name < strtab_size | |
870 | + ? strtab + psym->st_name : "<corrupt>"); | |
871 | ||
872 | if (section->sh_type == SHT_DYNSYM && | |
873 | version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0) | |
874 | @@ -6608,12 +6713,14 @@ process_symbol_table (FILE *file) | |
875 | sizeof data + si * sizeof (vers_data)); | |
876 | ||
877 | get_data (&data, file, offset + si * sizeof (vers_data), | |
878 | - sizeof (data), _("version data")); | |
879 | + sizeof (data), 1, _("version data")); | |
880 | ||
881 | vers_data = byte_get (data, 2); | |
882 | ||
883 | - is_nobits = (SECTION_HEADER (psym->st_shndx)->sh_type | |
884 | - == SHT_NOBITS); | |
885 | + is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx) | |
886 | + < elf_header.e_shnum | |
887 | + && SECTION_HEADER (psym->st_shndx)->sh_type | |
888 | + == SHT_NOBITS); | |
889 | ||
890 | check_def = (psym->st_shndx != SHN_UNDEF); | |
891 | ||
892 | @@ -6635,7 +6742,7 @@ process_symbol_table (FILE *file) | |
893 | { | |
894 | unsigned long vna_off; | |
895 | ||
896 | - get_data (&evn, file, offset, sizeof (evn), | |
897 | + get_data (&evn, file, offset, sizeof (evn), 1, | |
898 | _("version need")); | |
899 | ||
900 | ivn.vn_aux = BYTE_GET (evn.vn_aux); | |
901 | @@ -6648,7 +6755,7 @@ process_symbol_table (FILE *file) | |
902 | Elf_External_Vernaux evna; | |
903 | ||
904 | get_data (&evna, file, vna_off, | |
905 | - sizeof (evna), | |
906 | + sizeof (evna), 1, | |
907 | _("version need aux (3)")); | |
908 | ||
909 | ivna.vna_other = BYTE_GET (evna.vna_other); | |
910 | @@ -6670,7 +6777,9 @@ process_symbol_table (FILE *file) | |
911 | if (ivna.vna_other == vers_data) | |
912 | { | |
913 | printf ("@%s (%d)", | |
914 | - strtab + ivna.vna_name, ivna.vna_other); | |
915 | + ivna.vna_name < strtab_size | |
916 | + ? strtab + ivna.vna_name : "<corrupt>", | |
917 | + ivna.vna_other); | |
918 | check_def = 0; | |
919 | } | |
920 | else if (! is_nobits) | |
921 | @@ -6699,7 +6808,7 @@ process_symbol_table (FILE *file) | |
922 | Elf_External_Verdef evd; | |
923 | ||
924 | get_data (&evd, file, offset, sizeof (evd), | |
925 | - _("version def")); | |
926 | + 1, _("version def")); | |
927 | ||
928 | ivd.vd_ndx = BYTE_GET (evd.vd_ndx); | |
929 | ivd.vd_aux = BYTE_GET (evd.vd_aux); | |
930 | @@ -6714,14 +6823,15 @@ process_symbol_table (FILE *file) | |
931 | offset += ivd.vd_aux; | |
932 | ||
933 | get_data (&evda, file, offset, sizeof (evda), | |
934 | - _("version def aux")); | |
935 | + 1, _("version def aux")); | |
936 | ||
937 | ivda.vda_name = BYTE_GET (evda.vda_name); | |
938 | ||
939 | if (psym->st_name != ivda.vda_name) | |
940 | printf ((vers_data & 0x8000) | |
941 | ? "@%s" : "@@%s", | |
942 | - strtab + ivda.vda_name); | |
943 | + ivda.vda_name < strtab_size | |
944 | + ? strtab + ivda.vda_name : "<corrupt>"); | |
945 | } | |
946 | } | |
947 | } | |
948 | @@ -6908,7 +7018,8 @@ dump_section (Elf_Internal_Shdr *section | |
949 | ||
950 | addr = section->sh_addr; | |
951 | ||
952 | - start = get_data (NULL, file, section->sh_offset, bytes, _("section data")); | |
953 | + start = get_data (NULL, file, section->sh_offset, 1, bytes, | |
954 | + _("section data")); | |
955 | if (!start) | |
956 | return 0; | |
957 | ||
958 | @@ -7164,7 +7275,7 @@ get_debug_info (FILE * file) | |
959 | return 0; | |
960 | ||
961 | length = section->sh_size; | |
962 | - start = get_data (NULL, file, section->sh_offset, section->sh_size, | |
963 | + start = get_data (NULL, file, section->sh_offset, 1, section->sh_size, | |
964 | _("extracting information from .debug_info section")); | |
965 | if (start == NULL) | |
966 | return 0; | |
967 | @@ -7195,7 +7306,7 @@ get_debug_info (FILE * file) | |
968 | } | |
969 | ||
970 | /* Then allocate an array to hold the information. */ | |
971 | - debug_information = malloc (num_units * sizeof * debug_information); | |
972 | + debug_information = cmalloc (num_units, sizeof * debug_information); | |
973 | if (debug_information == NULL) | |
974 | { | |
975 | error (_("Not enough memory for a debug info array of %u entries"), | |
976 | @@ -8482,7 +8593,7 @@ load_debug_loc (FILE *file) | |
977 | ||
978 | debug_loc_size = sec->sh_size; | |
979 | ||
980 | - debug_loc_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size, | |
981 | + debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size, | |
982 | _("debug_loc section data")); | |
983 | } | |
984 | ||
985 | @@ -8593,7 +8704,7 @@ load_debug_str (FILE *file) | |
986 | ||
987 | debug_str_size = sec->sh_size; | |
988 | ||
989 | - debug_str_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size, | |
990 | + debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size, | |
991 | _("debug_str section data")); | |
992 | } | |
993 | ||
994 | @@ -8698,7 +8809,7 @@ load_debug_range (FILE *file) | |
995 | ||
996 | debug_range_size = sec->sh_size; | |
997 | ||
998 | - debug_range_contents = get_data (NULL, file, sec->sh_offset, sec->sh_size, | |
999 | + debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size, | |
1000 | _("debug_range section data")); | |
1001 | } | |
1002 | ||
1003 | @@ -9217,8 +9328,10 @@ debug_apply_rela_addends (FILE *file, | |
1004 | Elf_Internal_Sym *sym; | |
1005 | ||
1006 | if (relsec->sh_type != SHT_RELA | |
1007 | + || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum | |
1008 | || SECTION_HEADER (relsec->sh_info) != section | |
1009 | - || relsec->sh_size == 0) | |
1010 | + || relsec->sh_size == 0 | |
1011 | + || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum) | |
1012 | continue; | |
1013 | ||
1014 | if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, | |
1015 | @@ -9370,7 +9483,7 @@ display_debug_info (Elf_Internal_Shdr *s | |
1016 | return 0; | |
1017 | } | |
1018 | ||
1019 | - begin = get_data (NULL, file, sec->sh_offset, sec->sh_size, | |
1020 | + begin = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size, | |
1021 | _("debug_abbrev section data")); | |
1022 | if (!begin) | |
1023 | return 0; | |
1024 | @@ -9660,8 +9773,8 @@ frame_need_space (Frame_Chunk *fc, int r | |
1025 | return; | |
1026 | ||
1027 | fc->ncols = reg + 1; | |
1028 | - fc->col_type = xrealloc (fc->col_type, fc->ncols * sizeof (short int)); | |
1029 | - fc->col_offset = xrealloc (fc->col_offset, fc->ncols * sizeof (int)); | |
1030 | + fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int)); | |
1031 | + fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int)); | |
1032 | ||
1033 | while (prev < fc->ncols) | |
1034 | { | |
1035 | @@ -9972,8 +10085,8 @@ display_debug_frames (Elf_Internal_Shdr | |
1036 | else | |
1037 | { | |
1038 | fc->ncols = cie->ncols; | |
1039 | - fc->col_type = xmalloc (fc->ncols * sizeof (short int)); | |
1040 | - fc->col_offset = xmalloc (fc->ncols * sizeof (int)); | |
1041 | + fc->col_type = xcmalloc (fc->ncols, sizeof (short int)); | |
1042 | + fc->col_offset = xcmalloc (fc->ncols, sizeof (int)); | |
1043 | memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); | |
1044 | memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); | |
1045 | fc->augmentation = cie->augmentation; | |
1046 | @@ -10284,8 +10397,8 @@ display_debug_frames (Elf_Internal_Shdr | |
1047 | printf (" DW_CFA_remember_state\n"); | |
1048 | rs = xmalloc (sizeof (Frame_Chunk)); | |
1049 | rs->ncols = fc->ncols; | |
1050 | - rs->col_type = xmalloc (rs->ncols * sizeof (short int)); | |
1051 | - rs->col_offset = xmalloc (rs->ncols * sizeof (int)); | |
1052 | + rs->col_type = xcmalloc (rs->ncols, sizeof (short int)); | |
1053 | + rs->col_offset = xcmalloc (rs->ncols, sizeof (int)); | |
1054 | memcpy (rs->col_type, fc->col_type, rs->ncols); | |
1055 | memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); | |
1056 | rs->next = remembered_state; | |
1057 | @@ -10505,7 +10618,7 @@ display_debug_section (Elf_Internal_Shdr | |
1058 | { | |
1059 | unsigned char *start; | |
1060 | ||
1061 | - start = get_data (NULL, file, section->sh_offset, length, | |
1062 | + start = get_data (NULL, file, section->sh_offset, 1, length, | |
1063 | _("debug section data")); | |
1064 | if (start == NULL) | |
1065 | { | |
1066 | @@ -10631,7 +10744,7 @@ process_mips_specific (FILE *file) | |
1067 | size_t cnt; | |
1068 | ||
1069 | elib = get_data (NULL, file, liblist_offset, | |
1070 | - liblistno * sizeof (Elf32_External_Lib), | |
1071 | + liblistno, sizeof (Elf32_External_Lib), | |
1072 | _("liblist")); | |
1073 | if (elib) | |
1074 | { | |
1075 | @@ -10719,11 +10832,11 @@ process_mips_specific (FILE *file) | |
1076 | while (sect->sh_type != SHT_MIPS_OPTIONS) | |
1077 | ++sect; | |
1078 | ||
1079 | - eopt = get_data (NULL, file, options_offset, sect->sh_size, | |
1080 | + eopt = get_data (NULL, file, options_offset, 1, sect->sh_size, | |
1081 | _("options")); | |
1082 | if (eopt) | |
1083 | { | |
1084 | - iopt = malloc ((sect->sh_size / sizeof (eopt)) * sizeof (*iopt)); | |
1085 | + iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt)); | |
1086 | if (iopt == NULL) | |
1087 | { | |
1088 | error (_("Out of memory")); | |
1089 | @@ -10915,7 +11028,7 @@ process_mips_specific (FILE *file) | |
1090 | return 0; | |
1091 | } | |
1092 | ||
1093 | - iconf = malloc (conflictsno * sizeof (*iconf)); | |
1094 | + iconf = cmalloc (conflictsno, sizeof (*iconf)); | |
1095 | if (iconf == NULL) | |
1096 | { | |
1097 | error (_("Out of memory")); | |
1098 | @@ -10927,7 +11040,7 @@ process_mips_specific (FILE *file) | |
1099 | Elf32_External_Conflict *econf32; | |
1100 | ||
1101 | econf32 = get_data (NULL, file, conflicts_offset, | |
1102 | - conflictsno * sizeof (*econf32), _("conflict")); | |
1103 | + conflictsno, sizeof (*econf32), _("conflict")); | |
1104 | if (!econf32) | |
1105 | return 0; | |
1106 | ||
1107 | @@ -10941,7 +11054,7 @@ process_mips_specific (FILE *file) | |
1108 | Elf64_External_Conflict *econf64; | |
1109 | ||
1110 | econf64 = get_data (NULL, file, conflicts_offset, | |
1111 | - conflictsno * sizeof (*econf64), _("conflict")); | |
1112 | + conflictsno, sizeof (*econf64), _("conflict")); | |
1113 | if (!econf64) | |
1114 | return 0; | |
1115 | ||
1116 | @@ -10981,6 +11094,7 @@ process_gnu_liblist (FILE *file) | |
1117 | Elf_Internal_Shdr *section, *string_sec; | |
1118 | Elf32_External_Lib *elib; | |
1119 | char *strtab; | |
1120 | + size_t strtab_size; | |
1121 | size_t cnt; | |
1122 | unsigned i; | |
1123 | ||
1124 | @@ -10994,15 +11108,19 @@ process_gnu_liblist (FILE *file) | |
1125 | switch (section->sh_type) | |
1126 | { | |
1127 | case SHT_GNU_LIBLIST: | |
1128 | - elib = get_data (NULL, file, section->sh_offset, section->sh_size, | |
1129 | + if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum) | |
1130 | + break; | |
1131 | + | |
1132 | + elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size, | |
1133 | _("liblist")); | |
1134 | ||
1135 | if (elib == NULL) | |
1136 | break; | |
1137 | string_sec = SECTION_HEADER (section->sh_link); | |
1138 | ||
1139 | - strtab = get_data (NULL, file, string_sec->sh_offset, | |
1140 | + strtab = get_data (NULL, file, string_sec->sh_offset, 1, | |
1141 | string_sec->sh_size, _("liblist string table")); | |
1142 | + strtab_size = string_sec->sh_size; | |
1143 | ||
1144 | if (strtab == NULL | |
1145 | || section->sh_entsize != sizeof (Elf32_External_Lib)) | |
1146 | @@ -11038,9 +11156,11 @@ process_gnu_liblist (FILE *file) | |
1147 | ||
1148 | printf ("%3lu: ", (unsigned long) cnt); | |
1149 | if (do_wide) | |
1150 | - printf ("%-20s", strtab + liblist.l_name); | |
1151 | + printf ("%-20s", liblist.l_name < strtab_size | |
1152 | + ? strtab + liblist.l_name : "<corrupt>"); | |
1153 | else | |
1154 | - printf ("%-20.20s", strtab + liblist.l_name); | |
1155 | + printf ("%-20.20s", liblist.l_name < strtab_size | |
1156 | + ? strtab + liblist.l_name : "<corrupt>"); | |
1157 | printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum, | |
1158 | liblist.l_version, liblist.l_flags); | |
1159 | } | |
1160 | @@ -11204,7 +11324,7 @@ process_corefile_note_segment (FILE *fil | |
1161 | if (length <= 0) | |
1162 | return 0; | |
1163 | ||
1164 | - pnotes = get_data (NULL, file, offset, length, _("notes")); | |
1165 | + pnotes = get_data (NULL, file, offset, 1, length, _("notes")); | |
1166 | if (!pnotes) | |
1167 | return 0; | |
1168 |