This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix seg-fault in readelf when scanniing a corrupt binary.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1a9155522d3d1f6aded1178ad7038e846b6d67ba

commit 1a9155522d3d1f6aded1178ad7038e846b6d67ba
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Sep 3 16:15:49 2015 +0100

    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.

Diff:
---
 binutils/ChangeLog |  7 +++++++
 binutils/readelf.c | 14 +++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

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
 	    {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]