From 75ec1fdbb797a389e4fe4aaf2e15358a070dcc19 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 3 Apr 2017 11:13:21 +0100 Subject: [PATCH] Fix runtime seg-fault in readelf when parsing a corrupt MIPS binary. PR binutils/21344 * readelf.c (process_mips_specific): Check for an out of range GOT entry before reading the module pointer. --- binutils/ChangeLog | 6 ++++++ binutils/readelf.c | 24 +++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index dee35e5f38..438ea7fcd1 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2017-04-03 Nick Clifton + + PR binutils/21344 + * readelf.c (process_mips_specific): Check for an out of range GOT + entry before reading the module pointer. + 2017-04-03 Nick Clifton PR binutils/21343 diff --git a/binutils/readelf.c b/binutils/readelf.c index 47736d6e93..3665221501 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -15464,14 +15464,24 @@ process_mips_specific (FILE * file) printf (_(" Lazy resolver\n")); if (ent == (bfd_vma) -1) goto got_print_fail; - if (data - && (byte_get (data + ent - pltgot, addr_size) - >> (addr_size * 8 - 1)) != 0) + + if (data) { - ent = print_mips_got_entry (data, pltgot, ent, data_end); - printf (_(" Module pointer (GNU extension)\n")); - if (ent == (bfd_vma) -1) - goto got_print_fail; + /* PR 21344 */ + if (data + ent - pltgot > data_end - addr_size) + { + error (_("Invalid got entry - %#lx - overflows GOT table\n"), ent); + goto got_print_fail; + } + + if (byte_get (data + ent - pltgot, addr_size) + >> (addr_size * 8 - 1) != 0) + { + ent = print_mips_got_entry (data, pltgot, ent, data_end); + printf (_(" Module pointer (GNU extension)\n")); + if (ent == (bfd_vma) -1) + goto got_print_fail; + } } printf ("\n");