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.
This commit is contained in:
Alan Modra
2017-10-17 21:57:29 +10:30
parent 7b7009999a
commit cf54ebff3b
2 changed files with 15 additions and 9 deletions

View File

@ -1,3 +1,9 @@
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> 2017-10-17 Alan Modra <amodra@gmail.com>
PR 22306 PR 22306

View File

@ -93,15 +93,20 @@ bad_size:
return FALSE; return FALSE;
} }
while (1) while (ptr != ptr_end)
{ {
unsigned int type = bfd_h_get_32 (abfd, ptr); unsigned int type;
unsigned int datasz = bfd_h_get_32 (abfd, ptr + 4); unsigned int datasz;
elf_property *prop; 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; ptr += 8;
if ((ptr + datasz) > ptr_end) if (datasz > (size_t) (ptr_end - ptr))
{ {
_bfd_error_handler _bfd_error_handler
(_("warning: %B: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x"), (_("warning: %B: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x"),
@ -183,11 +188,6 @@ bad_size:
next: next:
ptr += (datasz + (align_size - 1)) & ~ (align_size - 1); ptr += (datasz + (align_size - 1)) & ~ (align_size - 1);
if (ptr == ptr_end)
break;
if (ptr > (ptr_end - 8))
goto bad_size;
} }
return TRUE; return TRUE;