Fixes illegal memory accesses triggereb by running a 32-bit binary version of objdump...
authorNick Clifton <nickc@redhat.com>
Fri, 6 Feb 2015 11:12:02 +0000 (11:12 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 6 Feb 2015 11:12:54 +0000 (11:12 +0000)
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
bfd/peXXigen.c
binutils/ChangeLog
binutils/dwarf.c

index a7fe73c..f12a610 100644 (file)
@@ -1,3 +1,10 @@
+2015-02-06  Nick Clifton  <nickc@redhat.com>
+
+       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  <hongjiu.lu@intel.com>
 
        PR ld/12365
index 45f1937..9feab3b 100644 (file)
@@ -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)
index 5182809..6cd306a 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-06  Nick Clifton  <nickc@redhat.com>
+
+       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  <amodra@gmail.com>
 
        PR binutils/17926
index aa19725..2edacb8 100644 (file)
@@ -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;