aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-10-17 21:57:29 +1030
committerAlan Modra <amodra@gmail.com>2017-10-17 22:12:45 +1030
commitcf54ebff3b7361989712fd9c0128a9b255578163 (patch)
tree02ff552d81ce251c1ff0eddc51003b932bddee55
parent7b7009999ab8daac9db776c850b7df6e1f586334 (diff)
downloadgdb-cf54ebff3b7361989712fd9c0128a9b255578163.zip
gdb-cf54ebff3b7361989712fd9c0128a9b255578163.tar.gz
gdb-cf54ebff3b7361989712fd9c0128a9b255578163.tar.bz2
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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf-properties.c18
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;