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] PR22307, Heap out of bounds read in _bfd_elf_parse_gnu_properties


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

commit cf54ebff3b7361989712fd9c0128a9b255578163
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Oct 17 21:57:29 2017 +1030

    PR22307, Heap out of bounds read in _bfd_elf_parse_gnu_properties
    
    When adding an unbounded increment to a pointer, you can't just check
    against the end of the buffer but also must check that overflow
    doesn't result in "negative" pointer movement.  Pointer comparisons
    are signed.  Better, check the increment against the space left using
    an unsigned comparison.
    
    	PR 22307
    	* elf-properties.c (_bfd_elf_parse_gnu_properties): Compare datasz
    	against size left rather than comparing pointers.  Reorganise loop.

Diff:
---
 bfd/ChangeLog        |  6 ++++++
 bfd/elf-properties.c | 18 +++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6f2c2b7..2373816 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
 2017-10-17  Alan Modra  <amodra@gmail.com>
 
+	PR 22307
+	* elf-properties.c (_bfd_elf_parse_gnu_properties): Compare datasz
+	against size left rather than comparing pointers.  Reorganise loop.
+
+2017-10-17  Alan Modra  <amodra@gmail.com>
+
 	PR 22306
 	* aoutx.h (aout_get_external_symbols): Handle stringsize of zero,
 	and error for any other size that doesn't cover the header word.
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
index f367aa6..bfb106e 100644
--- a/bfd/elf-properties.c
+++ b/bfd/elf-properties.c
@@ -93,15 +93,20 @@ bad_size:
       return FALSE;
     }
 
-  while (1)
+  while (ptr != ptr_end)
     {
-      unsigned int type = bfd_h_get_32 (abfd, ptr);
-      unsigned int datasz = bfd_h_get_32 (abfd, ptr + 4);
+      unsigned int type;
+      unsigned int datasz;
       elf_property *prop;
 
+      if ((size_t) (ptr_end - ptr) < 8)
+	goto bad_size;
+
+      type = bfd_h_get_32 (abfd, ptr);
+      datasz = bfd_h_get_32 (abfd, ptr + 4);
       ptr += 8;
 
-      if ((ptr + datasz) > ptr_end)
+      if (datasz > (size_t) (ptr_end - ptr))
 	{
 	  _bfd_error_handler
 	    (_("warning: %B: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x"),
@@ -183,11 +188,6 @@ bad_size:
 
 next:
       ptr += (datasz + (align_size - 1)) & ~ (align_size - 1);
-      if (ptr == ptr_end)
-	break;
-
-      if (ptr > (ptr_end - 8))
-	goto bad_size;
     }
 
   return TRUE;


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