CVE-2016-7417: Improper Input Validation (CWE-20)
value: ext/spl/spl_array.c in PHP before 5.6.26 and 7.x before 7.0.11 proceeds with SplArray unserialization without validating a return value and data type, which allows remote attackers to cause a denial of service or possibly have unspecified other impact via crafted serialized data.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 9.8
Published: 2016-09-17T21:59Z
Repository: https://github.com/php/php-src
Language: C
Files changed: ext/spl/spl_array.c, ext/spl/tests/bug73029.phpt
Commit date: 2016-09-12 21:04:23 -0700
Commit message: Fix bug #73029 - Missing type check when unserializing SplArray

Diff: diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 42a8e7aa449..700d6093dd5 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -306,11 +306,11 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
 	char *key;
 	uint len;
 	long index;
 	HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
-	if (!offset) {
+	if (!offset || !ht) {
 		return &EG(uninitialized_zval_ptr);
 	}
 
 	if ((type == BP_VAR_W || type == BP_VAR_RW) && (ht->nApplyCount > 0)) {
 		zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
@@ -624,11 +624,11 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
 
 	if (!value) {
 		HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
 		switch(Z_TYPE_P(offset)) {
-			case IS_STRING: 
+			case IS_STRING:
 				if (zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &tmp) != FAILURE) {
 					if (check_empty == 2) {
 						return 1;
 					}
 				} else {
@@ -636,11 +636,11 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
 				}
 				break;
 
 			case IS_DOUBLE:
 			case IS_RESOURCE:
-			case IS_BOOL: 
+			case IS_BOOL:
 			case IS_LONG:
 				if (offset->type == IS_DOUBLE) {
 					index = (long)Z_DVAL_P(offset);
 				} else {
 					index = Z_LVAL_P(offset);
@@ -1808,11 +1808,13 @@ SPL_METHOD(Array, unserialize)
 		}
 		intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK;
 		intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK;
 		zval_ptr_dtor(&intern->array);
 		ALLOC_INIT_ZVAL(intern->array);
-		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)
+				|| (Z_TYPE_P(intern->array) != IS_ARRAY && Z_TYPE_P(intern->array) != IS_OBJECT)) {
+			zval_ptr_dtor(&intern->array);
 			goto outexcept;
 		}
 		var_push_dtor(&var_hash, &intern->array);
 	}
 	if (*p != ';') {
diff --git a/ext/spl/tests/bug73029.phpt b/ext/spl/tests/bug73029.phpt
new file mode 100644
index 00000000000..a379f8005e4
--- /dev/null
+++ b/ext/spl/tests/bug73029.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #73029: Missing type check when unserializing SplArray
+--FILE--
+<?php
+try {
+$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
+$m = unserialize($a);
+$x = $m[2];
+} catch(UnexpectedValueException $e) {
+	print $e->getMessage() . "\n";
+}
+?>
+DONE
+--EXPECTF--
+Error at offset 10 of 19 bytes
+DONE

Vulnerable code: 	if (!offset) {
			case IS_STRING: 
			case IS_BOOL: 
		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {
Fixed code: 	if (!offset || !ht) {
			case IS_STRING:
			case IS_BOOL:
		if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)
				|| (Z_TYPE_P(intern->array) != IS_ARRAY && Z_TYPE_P(intern->array) != IS_OBJECT)) {
			zval_ptr_dtor(&intern->array);
--TEST--
Bug #73029: Missing type check when unserializing SplArray
--FILE--
<?php
try {
$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
$m = unserialize($a);
$x = $m[2];
} catch(UnexpectedValueException $e) {
	print $e->getMessage() . "\n";
}
?>
DONE
--EXPECTF--
Error at offset 10 of 19 bytes
DONE