From 72c61a0d1ef445f99305859b66450da60ec6e0cb Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 12 Jan 2015 16:08:41 +0000 Subject: [PATCH] More fixes for memory access errors when running readelf on fuzzed binaries. PR binutils/17531 * dwarf.c (process_debug_info): Check for abbrev_base being larger than the section size. (process_cu_tu_index): Use xcalloc2 to allocate the CU and TU arrays. (xcalloc2): New function. Like xcalloc, but checks for overflow. * dwarf.h (xcalloc2): Prototype. --- binutils/ChangeLog | 10 ++++++++++ binutils/dwarf.c | 22 +++++++++++++++++++--- binutils/dwarf.h | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 9458a84211f..75c29c851b5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2015-01-12 Nick Clifton + + PR binutils/17531 + * dwarf.c (process_debug_info): Check for abbrev_base being larger + than the section size. + (process_cu_tu_index): Use xcalloc2 to allocate the CU and TU + arrays. + (xcalloc2): New function. Like xcalloc, but checks for overflow. + * dwarf.h (xcalloc2): Prototype. + 2015-01-12 Alan Modra * prdbg.c (print_debugging_info): Don't use void* for function diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 2500a49011b..19b4b44cc79 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2466,6 +2466,11 @@ process_debug_info (struct dwarf_section *section, warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"), (unsigned long) compunit.cu_abbrev_offset, (unsigned long) abbrev_size); + /* PR 17531: file:4bcd9ce9. */ + else if (abbrev_base >= abbrev_size) + warn (_("Debug info is corrupted, abbrev base (%lx) is larger than abbrev section size (%lx)\n"), + (unsigned long) abbrev_base, + (unsigned long) abbrev_size); else process_abbrev_section (((unsigned char *) debug_displays [abbrev_sec].section.start @@ -6832,7 +6837,7 @@ process_cu_tu_index (struct dwarf_section *section, int do_display) /* PR 17512: file: 002-376-0.004. */ if (section->size < 24) { - warn (_("Section %s is too small to contain a CU/TU header"), + warn (_("Section %s is too small to contain a CU/TU header\n"), section->name); return 0; } @@ -6942,13 +6947,13 @@ process_cu_tu_index (struct dwarf_section *section, int do_display) if (is_tu_index) { tu_count = nused; - tu_sets = xcmalloc (nused, sizeof (struct cu_tu_set)); + tu_sets = xcalloc2 (nused, sizeof (struct cu_tu_set)); this_set = tu_sets; } else { cu_count = nused; - cu_sets = xcmalloc (nused, sizeof (struct cu_tu_set)); + cu_sets = xcalloc2 (nused, sizeof (struct cu_tu_set)); this_set = cu_sets; } } @@ -7152,6 +7157,17 @@ cmalloc (size_t nmemb, size_t size) return xmalloc (nmemb * size); } +/* Like xcalloc, but verifies that the first paramer is not too large. */ +void * +xcalloc2 (size_t nmemb, size_t size) +{ + /* Check for overflow. */ + if (nmemb >= ~(size_t) 0 / size) + return NULL; + + return xcalloc (nmemb, size); +} + /* Like xmalloc, but takes two parameters. Note: does *not* initialise the allocated memory to zero. */ void * diff --git a/binutils/dwarf.h b/binutils/dwarf.h index e8a768ec4fe..54dcbc77ffc 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -251,6 +251,7 @@ extern void dwarf_select_sections_all (void); extern unsigned int * find_cu_tu_set (void *, unsigned int); extern void * cmalloc (size_t, size_t); +extern void * xcalloc2 (size_t, size_t); extern void * xcmalloc (size_t, size_t); extern void * xcrealloc (void *, size_t, size_t); -- 2.30.2