diff options
author | Nick Clifton <nickc@redhat.com> | 2017-04-03 11:13:21 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-04-03 11:13:21 +0100 |
commit | 75ec1fdbb797a389e4fe4aaf2e15358a070dcc19 (patch) | |
tree | a83b024d470382360aa9003c6308ab069cbcc688 | |
parent | f32ba72991d2406b21ab17edc234a2f3fa7fb23d (diff) | |
download | fsf-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/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/readelf.c | 26 |
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"); |