[Pkg-php-commits] [php/debian-lenny] Fix CVE-2010-2225: use-after-free in the SplObjectStorage unserializer

Raphael Geissert geissert at debian.org
Fri Aug 6 19:30:26 UTC 2010


---
 debian/patches/CVE-2010-2225.patch |  135 ++++++++++++++++++++++++++++++++++++
 debian/patches/series              |    1 +
 2 files changed, 136 insertions(+), 0 deletions(-)
 create mode 100644 debian/patches/CVE-2010-2225.patch

diff --git a/debian/patches/CVE-2010-2225.patch b/debian/patches/CVE-2010-2225.patch
new file mode 100644
index 0000000..2ead590
--- /dev/null
+++ b/debian/patches/CVE-2010-2225.patch
@@ -0,0 +1,135 @@
+Index: php/ext/spl/spl_observer.c
+===================================================================
+--- php.orig/ext/spl/spl_observer.c
++++ php/ext/spl/spl_observer.c
+@@ -182,6 +182,21 @@ SPL_METHOD(SplObjectStorage, detach)
+ 	intern->index = 0;
+ } /* }}} */
+ 
++int spl_object_storage_contains(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */
++{
++#if HAVE_PACKED_OBJECT_VALUE
++	return zend_hash_exists(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value));
++#else
++	{
++		zend_object_value zvalue;
++		memset(&zvalue, 0, sizeof(zend_object_value));
++		zvalue.handle = Z_OBJ_HANDLE_P(obj);
++		zvalue.handlers = Z_OBJ_HT_P(obj);
++		return zend_hash_exists(&intern->storage, (char*)&zvalue, sizeof(zend_object_value));
++	}
++#endif
++} /* }}} */
++
+ /* {{{ proto bool SplObjectStorage::contains($obj)
+  Determine whethe an object is contained in the storage */
+ SPL_METHOD(SplObjectStorage, contains)
+@@ -193,17 +208,7 @@ SPL_METHOD(SplObjectStorage, contains)
+ 		return;
+ 	}
+ 
+-#if HAVE_PACKED_OBJECT_VALUE
+-	RETURN_BOOL(zend_hash_exists(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value)));
+-#else
+-	{
+-		zend_object_value zvalue;
+-		memset(&zvalue, 0, sizeof(zend_object_value));
+-		zvalue.handle = Z_OBJ_HANDLE_P(obj);
+-		zvalue.handlers = Z_OBJ_HT_P(obj);
+-		RETURN_BOOL(zend_hash_exists(&intern->storage, (char*)&zvalue, sizeof(zend_object_value)));
+-	}
+-#endif
++	RETURN_BOOL(spl_object_storage_contains(intern, obj TSRMLS_CC));
+ } /* }}} */
+ 
+ /* {{{ proto int SplObjectStorage::count()
+@@ -362,11 +367,22 @@ SPL_METHOD(SplObjectStorage, unserialize
+ 			goto outexcept;
+ 		}
+ 		++p;
++		if(*p != 'O' && *p != 'C' && *p != 'r') {
++			goto outexcept;
++		}
+ 		ALLOC_INIT_ZVAL(pentry);
+ 		if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+ 			zval_ptr_dtor(&pentry);
+ 			goto outexcept;
+ 		}
++		if(Z_TYPE_P(pentry) != IS_OBJECT) {
++			zval_ptr_dtor(&pentry);
++			goto outexcept;
++		}
++		if(spl_object_storage_contains(intern, pentry TSRMLS_CC)) {
++			zval_ptr_dtor(&pentry);
++			continue;
++		}
+ 		spl_object_storage_attach(intern, pentry TSRMLS_CC);
+ 		zval_ptr_dtor(&pentry);
+ 	}
+Index: php/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt
+===================================================================
+--- /dev/null
++++ php/ext/spl/tests/SplObjectStorage_unserialize_bad.phpt
+@@ -0,0 +1,24 @@
++--TEST--
++SPL: Test that serialized blob contains unique elements (CVE-2010-2225)
++--FILE--
++<?php
++
++$badblobs = array(
++'x:i:2;i:0;;i:0;;m:a:0:{}',
++'x:i:2;O:8:"stdClass":0:{};R:1;;m:a:0:{}',
++'x:i:3;O:8:"stdClass":0:{};r:1;;r:1;;m:a:0:{}',
++);
++foreach($badblobs as $blob) {
++try {
++  $so = new SplObjectStorage();
++  $so->unserialize($blob);
++  var_dump($so);
++} catch(UnexpectedValueException $e) {
++	echo $e->getMessage()."\n";
++}
++}
++--EXPECTF--
++Error at offset 6 of 24 bytes
++Error at offset 26 of 39 bytes
++object(SplObjectStorage)#2 (0) {
++}
+Index: php/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt
+===================================================================
+--- /dev/null
++++ php/ext/spl/tests/SplObjectStorage_unserialize_nested.phpt
+@@ -0,0 +1,33 @@
++--TEST--
++SPL: Test unserializing tested & linked storage
++--FILE--
++<?php
++$o = new StdClass();
++$a = new StdClass();
++
++$o->a = $a;
++
++$so = new SplObjectStorage();
++
++$so->attach($o);
++$so->attach($a);
++
++$s = serialize($so);
++echo $s."\n";
++
++$so1 = unserialize($s);
++var_dump($so1);
++foreach($so1 as $obj) {
++  var_dump($obj);
++}
++--EXPECTF--
++C:16:"SplObjectStorage":66:{x:i:2;O:8:"stdClass":1:{s:1:"a";O:8:"stdClass":0:{}};r:2;;m:a:0:{}}
++object(SplObjectStorage)#4 (0) {
++}
++object(stdClass)#5 (1) {
++  ["a"]=>
++  object(stdClass)#6 (0) {
++  }
++}
++object(stdClass)#6 (0) {
++}
diff --git a/debian/patches/series b/debian/patches/series
index 0cfbb4c..7d1ee35 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -68,3 +68,4 @@ CVE-2009-4142.patch
 CVE-2009-4143.patch
 CVE-2010-0397.patch
 CVE-2010-1917.patch
+CVE-2010-2225.patch
-- 
1.7.1





More information about the Pkg-php-commits mailing list