Fix illegal memory access errors triggered by running srconv on fuzzed binaries.
authorNick Clifton <nickc@redhat.com>
Fri, 13 Feb 2015 12:14:05 +0000 (12:14 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 13 Feb 2015 12:14:05 +0000 (12:14 +0000)
PR binutils/17512
* dwarf.c (read_leb128): Fix test for shift becoming too large.

* coffgrok.c (do_define): Add check for type size overflow.
* srconv.c (walk_tree_sfile): Check that enough sections are
available before parsing.
(prescan): Likewise.

binutils/ChangeLog
binutils/coffgrok.c
binutils/srconv.c

index 9b835dd280f40911e8829704311ad19758c1cbca..4325f3aeb95aaa6790082a9755dc6136fc1237b5 100644 (file)
@@ -1,3 +1,13 @@
+2015-02-13  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/17512
+       * dwarf.c (read_leb128): Fix test for shift becoming too large.
+
+       * coffgrok.c (do_define): Add check for type size overflow.
+       * srconv.c (walk_tree_sfile): Check that enough sections are
+       available before parsing.
+       (prescan): Likewise.
+
 2015-02-13  Alan Modra  <amodra@gmail.com>
 
        * dwarf.c: Formatting, whitespace.
index 2bbfdc45b42bc4af07ccdc87a24eb6a6a21b952a..0b953e8d6bd8ce02e38738f88aad6557af2f4e44 100644 (file)
@@ -668,12 +668,10 @@ do_define (unsigned int i, struct coff_scope *b)
 
          if (!is->init)
            {
-             long high = s->where->offset + s->type->size; 
-
              is->low = s->where->offset;
-             is->high = high;
+             is->high = s->where->offset + s->type->size; 
              /* PR 17512: file: 37e7a80d.  */
-             if (is->high != high)
+             if (is->high < s->where->offset)
                fatal (_("Out of range type size: %u"), s->type->size);
              is->init = 1;
              is->parent = s->where->section;
index 63c6940e36cd7f8f72ff47881116f408cef9f17c..7abbb66c55c66c6d70546854fc3c0eabd9ba5a3e 100644 (file)
@@ -1204,6 +1204,8 @@ walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile)
 static void
 wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile)
 {
+  if (p->nsections < 4)
+    return;
   walk_tree_sfile (p->sections + 4, sfile);
 }
 
@@ -1705,6 +1707,9 @@ prescan (struct coff_ofile *otree)
   struct coff_symbol *s;
   struct coff_section *common_section;
 
+  if (otree->nsections < 3)
+    return;
+
   /* Find the common section - always section 3.  */
   common_section = otree->sections + 3;
 
@@ -1715,7 +1720,6 @@ prescan (struct coff_ofile *otree)
       if (s->visible->type == coff_vis_common)
        {
          struct coff_where *w = s->where;
-
          /*      s->visible->type = coff_vis_ext_def; leave it as common */
          common_section->size = align (common_section->size);
          w->offset = common_section->size + common_section->address;