aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-09-03 16:15:49 +0100
committerNick Clifton <nickc@redhat.com>2015-09-03 16:15:49 +0100
commit1a9155522d3d1f6aded1178ad7038e846b6d67ba (patch)
treef79b0fa78874cdbd0bd46c0758d058b8853f405f /binutils
parent39edd165f42176f8c1d40e08d63f344f10241870 (diff)
downloadgdb-1a9155522d3d1f6aded1178ad7038e846b6d67ba.zip
gdb-1a9155522d3d1f6aded1178ad7038e846b6d67ba.tar.gz
gdb-1a9155522d3d1f6aded1178ad7038e846b6d67ba.tar.bz2
Fix seg-fault in readelf when scanniing a corrupt binary.
PR binutils/18879 * readelf.c (get_unwind_section_word): Check for negative offsets and very small sections. (dump_arm_unwind): Warn if the table offset is too large.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog7
-rw-r--r--binutils/readelf.c14
2 files changed, 20 insertions, 1 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index c2406da..ae9c995 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2015-09-03 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/18879
+ * readelf.c (get_unwind_section_word): Check for negative offsets
+ and very small sections.
+ (dump_arm_unwind): Warn if the table offset is too large.
+
2015-08-28 H.J. Lu <hongjiu.lu@intel.com>
* Makefile.am (TOOL_PROGS): Add readelf.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6298f1e..12fb415 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7518,7 +7518,10 @@ get_unwind_section_word (struct arm_unw_aux_info * aux,
return FALSE;
/* If the offset is invalid then fail. */
- if (word_offset > sec->sh_size - 4)
+ if (word_offset > (sec->sh_size - 4)
+ /* PR 18879 */
+ || (sec->sh_size < 5 && word_offset >= sec->sh_size)
+ || ((bfd_signed_vma) word_offset) < 0)
return FALSE;
/* Get the word at the required offset. */
@@ -8301,6 +8304,15 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
{
table_sec = section_headers + entry_addr.section;
table_offset = entry_addr.offset;
+ /* PR 18879 */
+ if (table_offset > table_sec->sh_size
+ || ((bfd_signed_vma) table_offset) < 0)
+ {
+ warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
+ (unsigned long) table_offset,
+ printable_section_name (table_sec));
+ continue;
+ }
}
else
{