aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2017-04-03 11:13:21 +0100
committerNick Clifton <nickc@redhat.com>2017-04-03 11:13:21 +0100
commit75ec1fdbb797a389e4fe4aaf2e15358a070dcc19 (patch)
treea83b024d470382360aa9003c6308ab069cbcc688
parentf32ba72991d2406b21ab17edc234a2f3fa7fb23d (diff)
downloadfsf-binutils-gdb-75ec1fdbb797a389e4fe4aaf2e15358a070dcc19.zip
fsf-binutils-gdb-75ec1fdbb797a389e4fe4aaf2e15358a070dcc19.tar.gz
fsf-binutils-gdb-75ec1fdbb797a389e4fe4aaf2e15358a070dcc19.tar.bz2
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.
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c26
2 files changed, 24 insertions, 8 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index dee35e5..438ea7f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,11 @@
2017-04-03 Nick Clifton <nickc@redhat.com>
+ 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 <nickc@redhat.com>
+
PR binutils/21343
* readelf.c (get_unwind_section_word): Fix snafu checking for
invalid word offsets in ARM unwind information.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 47736d6..3665221 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)
- {
- 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;
+
+ if (data)
+ {
+ /* 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");