diff options
author | Nick Clifton <nickc@redhat.com> | 2014-11-13 10:45:50 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-11-13 10:45:50 +0000 |
commit | 3102e897eeda28961a32826095befef5c4a74097 (patch) | |
tree | 443057786ff6a438191a01b8ff8b9036cd0fc99e /binutils | |
parent | a59add0c2ed21c03efc8b39e333564d7713a7ccc (diff) | |
download | gdb-3102e897eeda28961a32826095befef5c4a74097.zip gdb-3102e897eeda28961a32826095befef5c4a74097.tar.gz gdb-3102e897eeda28961a32826095befef5c4a74097.tar.bz2 |
More fixes for readelf problems reading corrupt files.
PR binutils/17531
* readelf.c (process_version_sections): If the read of the version
def information fails, make sure that the external verdef data is
not used.
(get_dynamic_data): Do not attempt to allocate memory for more
dynamic data than there is in the file. If the read fails, free
the allocated buffer.
(process_symbol_table): Do not print dynamic information if we
were unable to read the dynamic symbol table.
(print_gnu_note): Do not print the note if the descsz is too
small.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 14 | ||||
-rw-r--r-- | binutils/readelf.c | 30 |
2 files changed, 40 insertions, 4 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3a094f3..0ae8034 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2014-11-13 Nick Clifton <nickc@redhat.com> + + PR binutils/17531 + * readelf.c (process_version_sections): If the read of the version + def information fails, make sure that the external verdef data is + not used. + (get_dynamic_data): Do not attempt to allocate memory for more + dynamic data than there is in the file. If the read fails, free + the allocated buffer. + (process_symbol_table): Do not print dynamic information if we + were unable to read the dynamic symbol table. + (print_gnu_note): Do not print the note if the descsz is too + small. + 2014-11-12 Nick Clifton <nickc@redhat.com> PR binutils/17512 diff --git a/binutils/readelf.c b/binutils/readelf.c index f94b270..964dfc6 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -9440,7 +9440,9 @@ process_version_sections (FILE * file) _("version def")) == NULL) { ivd.vd_next = 0; - ivd.vd_ndx = 0; + /* PR 17531: file: 046-1082287-0.004. */ + ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1; + break; } else { @@ -9777,6 +9779,15 @@ get_dynamic_data (FILE * file, size_t number, unsigned int ent_size) unsigned char * e_data; bfd_vma * i_data; + /* Be kind to memory chekers (eg valgrind, address sanitizer) by not + attempting to allocate memory when the read is bound to fail. */ + if (ent_size * number > current_file_size) + { + error (_("Invalid number of dynamic entries: %lu\n"), + (unsigned long) number); + return NULL; + } + e_data = (unsigned char *) cmalloc (number, ent_size); if (e_data == NULL) { @@ -9787,7 +9798,9 @@ get_dynamic_data (FILE * file, size_t number, unsigned int ent_size) if (fread (e_data, ent_size, number, file) != number) { - error (_("Unable to read in dynamic data\n")); + error (_("Unable to read in %lu bytes of dynamic data\n"), + (unsigned long) (number * ent_size)); + free (e_data); return NULL; } @@ -9821,7 +9834,8 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn) if (dynamic_symbols == NULL || si >= num_dynamic_syms) { - printf (_("<No info available>\n")); + printf (_("<No info available for dynamic symbol number %lu>\n"), + (unsigned long) si); return; } @@ -10038,7 +10052,8 @@ process_symbol_table (FILE * file) if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH) && do_syms && do_using_dynamic - && dynamic_strings != NULL) + && dynamic_strings != NULL + && dynamic_symbols != NULL) { unsigned long hn; @@ -14242,6 +14257,13 @@ print_gnu_note (Elf_Internal_Note *pnote) unsigned long os, major, minor, subminor; const char *osname; + /* PR 17531: file: 030-599401-0.004. */ + if (pnote->descsz < 16) + { + printf (_(" <corrupt GNU_ABI_TAG>\n")); + break; + } + os = byte_get ((unsigned char *) pnote->descdata, 4); major = byte_get ((unsigned char *) pnote->descdata + 4, 4); minor = byte_get ((unsigned char *) pnote->descdata + 8, 4); |