CVE-2016-10161 (Other, published 2017-01-24T21:59Z)
Description: value: The object_common1 function in ext/standard/var_unserializer.c in PHP before 5.6.30, 7.0.x before 7.0.15, and 7.1.x before 7.1.1 allows remote attackers to cause a denial of service (buffer over-read and application crash) via crafted serialized data that is mishandled in a finish_nested_data call.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/php/php-src
Files changed:
ext/standard/tests/serialize/bug73825.phpt
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re
Commit message: Fix bug #73825 - Heap out of bounds read on unserialize in finish_nested_data()


Vulnerable code:
		return 0;
#line 496 "ext/standard/var_unserializer.c"
#line 861 "ext/standard/var_unserializer.re"
#line 558 "ext/standard/var_unserializer.c"
#line 855 "ext/standard/var_unserializer.re"
#line 607 "ext/standard/var_unserializer.c"
#line 708 "ext/standard/var_unserializer.re"
#line 785 "ext/standard/var_unserializer.c"
#line 699 "ext/standard/var_unserializer.re"
	return object_common2(UNSERIALIZE_PASSTHRU,
			object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
#line 819 "ext/standard/var_unserializer.c"
#line 678 "ext/standard/var_unserializer.re"
#line 861 "ext/standard/var_unserializer.c"
#line 643 "ext/standard/var_unserializer.re"
#line 917 "ext/standard/var_unserializer.c"
#line 610 "ext/standard/var_unserializer.re"
#line 971 "ext/standard/var_unserializer.c"
#line 600 "ext/standard/var_unserializer.re"
#line 1069 "ext/standard/var_unserializer.c"
#line 585 "ext/standard/var_unserializer.re"
#line 1143 "ext/standard/var_unserializer.c"
#line 558 "ext/standard/var_unserializer.re"
#line 1197 "ext/standard/var_unserializer.c"
#line 551 "ext/standard/var_unserializer.re"
#line 1212 "ext/standard/var_unserializer.c"
#line 544 "ext/standard/var_unserializer.re"
#line 1222 "ext/standard/var_unserializer.c"
#line 521 "ext/standard/var_unserializer.re"
#line 1268 "ext/standard/var_unserializer.c"
#line 500 "ext/standard/var_unserializer.re"
#line 1312 "ext/standard/var_unserializer.c"
#line 863 "ext/standard/var_unserializer.re"
		return 0;
	return object_common2(UNSERIALIZE_PASSTHRU,
			object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));

Fixed code:
--TEST--
Bug #73825 Heap out of bounds read on unserialize in finish_nested_data()
--FILE--
<?php
$obj = unserialize('O:8:"00000000":');
var_dump($obj);
?>
--EXPECTF--
Warning: Bad unserialize data in %sbug73825.php on line %d

Notice: unserialize(): Error at offset 13 of 15 bytes in %sbug73825.php on line %d
bool(false)
	if( *p >= max - 2) {
		zend_error(E_WARNING, "Bad unserialize data");
		return -1;
	}

		return -1;
#line 501 "ext/standard/var_unserializer.c"
#line 875 "ext/standard/var_unserializer.re"
#line 563 "ext/standard/var_unserializer.c"
#line 869 "ext/standard/var_unserializer.re"
#line 612 "ext/standard/var_unserializer.c"
#line 717 "ext/standard/var_unserializer.re"
	if (elements < 0) {
	   efree(class_name);
	   return 0;
	}

#line 795 "ext/standard/var_unserializer.c"
#line 704 "ext/standard/var_unserializer.re"
	long elements;
	elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
	if (elements < 0) {
		return 0;
	}
	return object_common2(UNSERIALIZE_PASSTHRU, elements);
#line 833 "ext/standard/var_unserializer.c"
#line 683 "ext/standard/var_unserializer.re"
#line 875 "ext/standard/var_unserializer.c"
#line 648 "ext/standard/var_unserializer.re"
#line 931 "ext/standard/var_unserializer.c"
#line 615 "ext/standard/var_unserializer.re"
#line 985 "ext/standard/var_unserializer.c"
#line 605 "ext/standard/var_unserializer.re"
#line 1083 "ext/standard/var_unserializer.c"
#line 590 "ext/standard/var_unserializer.re"
#line 1157 "ext/standard/var_unserializer.c"
#line 563 "ext/standard/var_unserializer.re"
#line 1211 "ext/standard/var_unserializer.c"
#line 556 "ext/standard/var_unserializer.re"
#line 1226 "ext/standard/var_unserializer.c"
#line 549 "ext/standard/var_unserializer.re"
#line 1236 "ext/standard/var_unserializer.c"
#line 526 "ext/standard/var_unserializer.re"
#line 1282 "ext/standard/var_unserializer.c"
#line 505 "ext/standard/var_unserializer.re"
#line 1326 "ext/standard/var_unserializer.c"
#line 877 "ext/standard/var_unserializer.re"
	if( *p >= max - 2) {
		zend_error(E_WARNING, "Bad unserialize data");
		return -1;
	}

		return -1;
	long elements;
	elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
	if (elements < 0) {
		return 0;
	}
	return object_common2(UNSERIALIZE_PASSTHRU, elements);
	if (elements < 0) {
	   efree(class_name);
	   return 0;
	}