[prev in list] [next in list] [prev in thread] [next in thread] 

List:       binutils-cvs
Subject:    [binutils-gdb/binutils-2_33-branch] PR25018, readelf crash on 32bits
From:       Alan Modra <amodra () sourceware ! org>
Date:       2019-09-25 2:18:26
Message-ID: 20190925021826.5835.qmail () sourceware ! org
[Download RAW message or body]

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

commit a11b3493ca2d5aabdc218197b92026098d7e2f57
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Sep 23 08:53:07 2019 +0930

    PR25018, readelf crash on 32bits
    
    Pointer comparisons after adding an offset just don't work to catch
    overflow when the offset is a larger type than the pointer.
    
    	PR 25018
    	* dwarf.c (get_type_signedness): Delete ineffective pointer
    	comparison check.  Properly range check uvalue offset on
    	recursive call.
    	(read_and_display_attr_value): Range check uvalue offset before
    	calling get_type_signedness.
    
    (cherry picked from commit b3fe587ed2c78d46132bd33e14f42449d410354b)

Diff:
---
 binutils/ChangeLog | 11 +++++++++++
 binutils/dwarf.c   |  8 ++++----
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 167e937..dd22321 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,14 @@
+2019-09-25  Alan Modra  <amodra@gmail.com>
+
+	Apply from master
+	2019-09-23  Alan Modra  <amodra@gmail.com>
+	PR 25018
+	* dwarf.c (get_type_signedness): Delete ineffective pointer
+	comparison check.  Properly range check uvalue offset on
+	recursive call.
+	(read_and_display_attr_value): Range check uvalue offset before
+	calling get_type_signedness.
+
 2019-09-19  Tamar Christina  <tamar.christina@arm.com>
 
 	* testsuite/binutils-all/objdump.exp (objdump -S): Update testcase.
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index df924e4..2fe469f 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -1999,9 +1999,6 @@ get_type_signedness (unsigned char *        start,
 
   * is_signed = FALSE;
 
-  if (data >= end)
-    return;
-
   abbrev_number = read_uleb128 (data, & bytes_read, end);
   data += bytes_read;
 
@@ -2042,6 +2039,8 @@ get_type_signedness (unsigned char *        start,
 		 NB/ We need to avoid infinite recursion.  */
 	      return;
 	    }
+	  if (uvalue >= (size_t) (end - start))
+	    return;
 	  get_type_signedness (start, start + uvalue, end, pointer_size,
 			       offset_size, dwarf_version, is_signed, TRUE);
 	  break;
@@ -2725,7 +2724,8 @@ read_and_display_attr_value (unsigned long           attribute,
   switch (attribute)
     {
     case DW_AT_type:
-      if (level >= 0 && level < MAX_CU_NESTING)
+      if (level >= 0 && level < MAX_CU_NESTING
+	  && uvalue < (size_t) (end - start))
 	{
 	  bfd_boolean is_signed = FALSE;
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic