aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-11-13 10:45:50 +0000
committerNick Clifton <nickc@redhat.com>2014-11-13 10:45:50 +0000
commit3102e897eeda28961a32826095befef5c4a74097 (patch)
tree443057786ff6a438191a01b8ff8b9036cd0fc99e /binutils
parenta59add0c2ed21c03efc8b39e333564d7713a7ccc (diff)
downloadgdb-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/ChangeLog14
-rw-r--r--binutils/readelf.c30
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);