From 3102e897eeda28961a32826095befef5c4a74097 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 13 Nov 2014 10:45:50 +0000 Subject: [PATCH] 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. --- binutils/ChangeLog | 14 ++++++++++++++ binutils/readelf.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3a094f38202..0ae803400b3 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2014-11-13 Nick Clifton + + 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 PR binutils/17512 diff --git a/binutils/readelf.c b/binutils/readelf.c index f94b270ca53..964dfc63c71 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 (_("\n")); + printf (_("\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 (_(" \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); -- 2.30.2