From 5929c344f957f93253efa4c3495a996789d48ae7 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 6 Feb 2015 11:12:02 +0000 Subject: [PATCH] Fixes illegal memory accesses triggereb by running a 32-bit binary version of objdump compiled on a 64-bit host. PR binutils/17512 * dwarf.c (display_debug_frames): Fix range checks to work on 32-bit binaries complied on a 64-bit host. * peXXigen.c (rsrc_print_resource_entries): Add range check for addresses that wrap around the address space. (rsrc_parse_entry): Likewise. --- bfd/ChangeLog | 7 +++++++ bfd/peXXigen.c | 29 +++++++++++++++++++---------- binutils/ChangeLog | 6 ++++++ binutils/dwarf.c | 11 +++++++---- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a7fe73ccb5c..f12a610b6de 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2015-02-06 Nick Clifton + + PR binutils/17512 + * peXXigen.c (rsrc_print_resource_entries): Add range check for + addresses that wrap around the address space. + (rsrc_parse_entry): Likewise. + 2015-02-03 H.J. Lu PR ld/12365 diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 45f1937e9b4..9feab3b7371 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -2302,6 +2302,7 @@ rsrc_print_resource_entries (FILE * file, bfd_vma rva_bias) { unsigned long entry, addr, size; + bfd_byte * leaf; if (data + 8 >= regions->section_end) return regions->section_end + 1; @@ -2382,18 +2383,21 @@ rsrc_print_resource_entries (FILE * file, regions, rva_bias); } - if (regions->section_start + entry + 16 >= regions->section_end) + leaf = regions->section_start + entry; + + if (leaf + 16 >= regions->section_end + /* PR 17512: file: 055dff7e. */ + || leaf < regions->section_start) return regions->section_end + 1; fprintf (file, _("%03x %*.s Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"), - (int) (entry), - indent, " ", - addr = (long) bfd_get_32 (abfd, regions->section_start + entry), - size = (long) bfd_get_32 (abfd, regions->section_start + entry + 4), - (int) bfd_get_32 (abfd, regions->section_start + entry + 8)); + (int) (entry), indent, " ", + addr = (long) bfd_get_32 (abfd, leaf), + size = (long) bfd_get_32 (abfd, leaf + 4), + (int) bfd_get_32 (abfd, leaf + 8)); /* Check that the reserved entry is 0. */ - if (bfd_get_32 (abfd, regions->section_start + entry + 12) != 0 + if (bfd_get_32 (abfd, leaf + 12) != 0 /* And that the data address/size is valid too. */ || (regions->section_start + (addr - rva_bias) + size > regions->section_end)) return regions->section_end + 1; @@ -3264,9 +3268,14 @@ rsrc_parse_entry (bfd * abfd, if (entry->value.leaf == NULL) return dataend; - addr = bfd_get_32 (abfd, datastart + val); - size = entry->value.leaf->size = bfd_get_32 (abfd, datastart + val + 4); - entry->value.leaf->codepage = bfd_get_32 (abfd, datastart + val + 8); + data = datastart + val; + if (data < datastart || data >= dataend) + return dataend; + + addr = bfd_get_32 (abfd, data); + size = entry->value.leaf->size = bfd_get_32 (abfd, data + 4); + entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8); + /* FIXME: We assume that the reserved field (data + 12) is OK. */ entry->value.leaf->data = bfd_malloc (size); if (entry->value.leaf->data == NULL) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 5182809c1a4..6cd306a83f4 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2015-02-06 Nick Clifton + + PR binutils/17512 + * dwarf.c (display_debug_frames): Fix range checks to work on + 32-bit binaries complied on a 64-bit host. + 2015-02-05 Alan Modra PR binutils/17926 diff --git a/binutils/dwarf.c b/binutils/dwarf.c index aa197256325..2edacb8392b 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -5949,6 +5949,7 @@ display_debug_frames (struct dwarf_section *section, { unsigned int reg, op, opa; unsigned long temp; + unsigned char * new_start; op = *start++; opa = op & 0x3f; @@ -6019,26 +6020,28 @@ display_debug_frames (struct dwarf_section *section, break; case DW_CFA_def_cfa_expression: temp = LEB (); - if (start + temp < start) + new_start = start + temp; + if (new_start < start) { warn (_("Corrupt CFA_def expression value: %lu\n"), temp); start = block_end; } else - start += temp; + start = new_start; break; case DW_CFA_expression: case DW_CFA_val_expression: reg = LEB (); temp = LEB (); - if (start + temp < start) + new_start = start + temp; + if (new_start < start) { /* PR 17512: file:306-192417-0.005. */ warn (_("Corrupt CFA expression value: %lu\n"), temp); start = block_end; } else - start += temp; + start = new_start; if (frame_need_space (fc, reg) >= 0) fc->col_type[reg] = DW_CFA_undefined; break; -- 2.30.2