aboutsummaryrefslogtreecommitdiff
path: root/binutils/coffgrok.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-02-26 22:16:16 +0000
committerNick Clifton <nickc@redhat.com>2015-02-26 22:16:16 +0000
commitd93c7787a0dd4261b8ac65a92a33196b62ef57b4 (patch)
treeb751d47d3eb56c2ae15b1229819c19227c52cbfb /binutils/coffgrok.c
parentc86934ceee0971a04bbfc145c7b9a53357c25c91 (diff)
downloadbinutils-d93c7787a0dd4261b8ac65a92a33196b62ef57b4.zip
binutils-d93c7787a0dd4261b8ac65a92a33196b62ef57b4.tar.gz
binutils-d93c7787a0dd4261b8ac65a92a33196b62ef57b4.tar.bz2
Fix arithmetic overflows running srconv on fuzzed binaries.
PR binutils/17512 * coffgrok.c (do_type): Check for an out of range tag index. Check for integer overflow computing array dimension. (do_define): Likewise.
Diffstat (limited to 'binutils/coffgrok.c')
-rw-r--r--binutils/coffgrok.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/binutils/coffgrok.c b/binutils/coffgrok.c
index 0b953e8..87b87c3 100644
--- a/binutils/coffgrok.c
+++ b/binutils/coffgrok.c
@@ -428,7 +428,16 @@ do_type (unsigned int i)
if (aux->x_sym.x_tagndx.p)
{
- unsigned int idx = INDEXOF (aux->x_sym.x_tagndx.p);
+ unsigned int idx;
+
+ /* PR 17512: file: e72f3988. */
+ if (aux->x_sym.x_tagndx.l < 0 || aux->x_sym.x_tagndx.p < rawsyms)
+ {
+ non_fatal (_("Invalid tag index %#lx encountered"), aux->x_sym.x_tagndx.l);
+ idx = 0;
+ }
+ else
+ idx = INDEXOF (aux->x_sym.x_tagndx.p);
if (idx >= rawcount)
{
@@ -515,7 +524,17 @@ do_type (unsigned int i)
++dimind;
ptr->type = coff_array_type;
- ptr->size = els * res->size;
+ /* PR 17512: file: ae1971e2.
+ Check for integer overflow. */
+ {
+ long long a, z;
+ a = els;
+ z = res->size;
+ a *= z;
+ ptr->size = (int) a;
+ if (ptr->size != a)
+ non_fatal (_("Out of range sum for els (%#x) * size (%#x)"), els, res->size);
+ }
ptr->u.array.dim = els;
ptr->u.array.array_of = res;
res = ptr;
@@ -669,7 +688,19 @@ do_define (unsigned int i, struct coff_scope *b)
if (!is->init)
{
is->low = s->where->offset;
- is->high = s->where->offset + s->type->size;
+ /* PR 17512: file: 37e7a80d.
+ Check for integer overflow computing low + size. */
+ {
+ long long a, z;
+
+ a = s->where->offset;
+ z = s->type->size;
+ a += z;
+ is->high = (int) a;
+ if (a != is->high)
+ non_fatal (_("Out of range sum for offset (%#x) + size (%#x)"),
+ is->low, s->type->size);
+ }
/* PR 17512: file: 37e7a80d. */
if (is->high < s->where->offset)
fatal (_("Out of range type size: %u"), s->type->size);