From 951eaaec17411eba4debe19781f6b8b54306256e Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 13 Feb 2015 12:14:05 +0000 Subject: [PATCH] Fix illegal memory access errors triggered by running srconv on fuzzed binaries. 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 | 10 ++++++++++ binutils/coffgrok.c | 6 ++---- binutils/srconv.c | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 9b835dd280f..4325f3aeb95 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2015-02-13 Nick Clifton + + 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 * dwarf.c: Formatting, whitespace. diff --git a/binutils/coffgrok.c b/binutils/coffgrok.c index 2bbfdc45b42..0b953e8d6bd 100644 --- a/binutils/coffgrok.c +++ b/binutils/coffgrok.c @@ -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; diff --git a/binutils/srconv.c b/binutils/srconv.c index 63c6940e36c..7abbb66c55c 100644 --- a/binutils/srconv.c +++ b/binutils/srconv.c @@ -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; -- 2.30.2