PR25018, readelf crash on 32bits

Alan Modra amodra@gmail.com
Sun Sep 22 23:38:00 GMT 2019


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.

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index df924e4050..2fe469f060 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;
 

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list