+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
_("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
{
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)
{
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;
}
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;
}
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;
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);