colder                                   Wed, 07 Jul 2010 21:55:17 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=301064

Log:
Fixed #51697 (Unsafe operations in free_storage of SPL iterators,
causes crashes during shutdown)

Bug: http://bugs.php.net/51697 (Assigned) Segfault in spl_iterators.c
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/spl/spl_iterators.c
    U   php/php-src/trunk/ext/spl/spl_iterators.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS	2010-07-07 20:03:04 UTC (rev 301063)
+++ php/php-src/branches/PHP_5_3/NEWS	2010-07-07 21:55:17 UTC (rev 301064)
@@ -7,6 +7,8 @@
   results and PHP crashes). (Felipe)
 - Fixed bug #52238 (Crash when an Exception occured in iterator_to_array).
   (Johannes)
+- Fixed bug #51697 (Unsafe operations in free_storage of SPL iterators,
+  causes crash during shutdown). (Etienne)

 01 Jul 2010, PHP 5.3.3 RC2
 - Fixed SplObjectStorage unserialization problems (CVE-2010-2225). (Stas)

Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_iterators.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/spl/spl_iterators.c	2010-07-07 20:03:04 UTC (rev 301063)
+++ php/php-src/branches/PHP_5_3/ext/spl/spl_iterators.c	2010-07-07 21:55:17 UTC (rev 301064)
@@ -131,7 +131,7 @@
 	spl_recursive_it_object   *object = (spl_recursive_it_object*)_iter->data;
 	zend_object_iterator      *sub_iter;

-	while (object->level) {
+	while (object->level > 0) {
 		sub_iter = object->iterators[object->level].iterator;
 		sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
 		zval_ptr_dtor(&object->iterators[object->level--].zobject);
@@ -139,10 +139,10 @@
 	object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
 	object->level = 0;

-	zval_ptr_dtor(&iter->zobject);
+	zval_ptr_dtor(&iter->zobject);
 	efree(iter);
 }
-
+
 static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthis TSRMLS_DC)
 {
 	zend_object_iterator      *sub_iter;
@@ -536,6 +536,18 @@
 	intern->iterators[0].state = RS_START;

 	zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+	if (EG(exception)) {
+		zend_object_iterator *sub_iter;
+
+		while (intern->level >= 0) {
+			sub_iter = intern->iterators[intern->level].iterator;
+			sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
+			zval_ptr_dtor(&intern->iterators[intern->level--].zobject);
+		}
+		efree(intern->iterators);
+		intern->iterators = NULL;
+	}
 }

 /* {{{ proto void RecursiveIteratorIterator::__construct(RecursiveIterator|IteratorAggregate it [, int mode = RIT_LEAVES_ONLY [, int flags = 0]]) throws InvalidArgumentException
@@ -778,11 +790,14 @@
 }

 /* {{{ spl_RecursiveIteratorIterator_dtor */
-static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+static void spl_RecursiveIteratorIterator_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
 {
 	spl_recursive_it_object   *object = (spl_recursive_it_object *)_object;
 	zend_object_iterator      *sub_iter;

+	/* call standard dtor */
+	zend_objects_destroy_object(_object, handle);
+
 	if (object->iterators) {
 		while (object->level >= 0) {
 			sub_iter = object->iterators[object->level].iterator;
@@ -792,7 +807,14 @@
 		efree(object->iterators);
 		object->iterators = NULL;
 	}
+}
+/* }}} */

+/* {{{ spl_RecursiveIteratorIterator_dtor */
+static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+{
+	spl_recursive_it_object   *object = (spl_recursive_it_object *)_object;
+
 	zend_object_std_dtor(&object->std TSRMLS_CC);
 	smart_str_free(&object->prefix[0]);
 	smart_str_free(&object->prefix[1]);
@@ -827,7 +849,7 @@
 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
 	zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

-	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
+	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_RecursiveIteratorIterator_dtor, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
 	retval.handlers = &spl_handlers_rec_it_it;
 	return retval;
 }
@@ -1909,17 +1931,27 @@

 #endif

-/* {{{ spl_dual_it_free_storage */
-static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+/* {{{ spl_dual_it_dtor */
+static void spl_dual_it_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
 {
 	spl_dual_it_object        *object = (spl_dual_it_object *)_object;

+	/* call standard dtor */
+	zend_objects_destroy_object(_object, handle);
+
 	spl_dual_it_free(object TSRMLS_CC);

 	if (object->inner.iterator) {
 		object->inner.iterator->funcs->dtor(object->inner.iterator TSRMLS_CC);
 	}
+}
+/* }}} */

+/* {{{ spl_dual_it_free_storage */
+static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+{
+	spl_dual_it_object        *object = (spl_dual_it_object *)_object;
+
 	if (object->inner.zobject) {
 		zval_ptr_dtor(&object->inner.zobject);
 	}
@@ -1969,7 +2001,7 @@
 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
 	zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

-	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC);
+	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_dual_it_dtor, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC);
 	retval.handlers = &spl_handlers_dual_it;
 	return retval;
 }

Modified: php/php-src/trunk/ext/spl/spl_iterators.c
===================================================================
--- php/php-src/trunk/ext/spl/spl_iterators.c	2010-07-07 20:03:04 UTC (rev 301063)
+++ php/php-src/trunk/ext/spl/spl_iterators.c	2010-07-07 21:55:17 UTC (rev 301064)
@@ -131,7 +131,7 @@
 	spl_recursive_it_object   *object = (spl_recursive_it_object*)_iter->data;
 	zend_object_iterator      *sub_iter;

-	while (object->level) {
+	while (object->level > 0) {
 		sub_iter = object->iterators[object->level].iterator;
 		sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
 		zval_ptr_dtor(&object->iterators[object->level--].zobject);
@@ -139,10 +139,10 @@
 	object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
 	object->level = 0;

-	zval_ptr_dtor(&iter->zobject);
+	zval_ptr_dtor(&iter->zobject);
 	efree(iter);
 }
-
+
 static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthis TSRMLS_DC)
 {
 	zend_object_iterator      *sub_iter;
@@ -536,6 +536,18 @@
 	intern->iterators[0].state = RS_START;

 	zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+	if (EG(exception)) {
+		zend_object_iterator *sub_iter;
+
+		while (intern->level >= 0) {
+			sub_iter = intern->iterators[intern->level].iterator;
+			sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
+			zval_ptr_dtor(&intern->iterators[intern->level--].zobject);
+		}
+		efree(intern->iterators);
+		intern->iterators = NULL;
+	}
 }

 /* {{{ proto void RecursiveIteratorIterator::__construct(RecursiveIterator|IteratorAggregate it [, int mode = RIT_LEAVES_ONLY [, int flags = 0]]) throws InvalidArgumentException
@@ -778,11 +790,14 @@
 }

 /* {{{ spl_RecursiveIteratorIterator_dtor */
-static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+static void spl_RecursiveIteratorIterator_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
 {
 	spl_recursive_it_object   *object = (spl_recursive_it_object *)_object;
 	zend_object_iterator      *sub_iter;

+	/* call standard dtor */
+	zend_objects_destroy_object(_object, handle);
+
 	if (object->iterators) {
 		while (object->level >= 0) {
 			sub_iter = object->iterators[object->level].iterator;
@@ -792,7 +807,14 @@
 		efree(object->iterators);
 		object->iterators = NULL;
 	}
+}
+/* }}} */

+/* {{{ spl_RecursiveIteratorIterator_free_storage */
+static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+{
+	spl_recursive_it_object   *object = (spl_recursive_it_object *)_object;
+
 	zend_object_std_dtor(&object->std TSRMLS_CC);
 	smart_str_free(&object->prefix[0]);
 	smart_str_free(&object->prefix[1]);
@@ -826,7 +848,7 @@
 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
 	object_properties_init(&intern->std, class_type);

-	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
+	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_RecursiveIteratorIterator_dtor, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
 	retval.handlers = &spl_handlers_rec_it_it;
 	return retval;
 }
@@ -1908,17 +1930,28 @@

 #endif

-/* {{{ spl_dual_it_free_storage */
-static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+/* {{{ spl_dual_it_dtor */
+static void spl_dual_it_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
 {
 	spl_dual_it_object        *object = (spl_dual_it_object *)_object;

+	/* call standard dtor */
+	zend_objects_destroy_object(_object, handle);
+
 	spl_dual_it_free(object TSRMLS_CC);

 	if (object->inner.iterator) {
 		object->inner.iterator->funcs->dtor(object->inner.iterator TSRMLS_CC);
 	}
+}
+/* }}} */

+/* {{{ spl_dual_it_free_storage */
+static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+{
+	spl_dual_it_object        *object = (spl_dual_it_object *)_object;
+
+
 	if (object->inner.zobject) {
 		zval_ptr_dtor(&object->inner.zobject);
 	}
@@ -1967,7 +2000,7 @@
 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
 	object_properties_init(&intern->std, class_type);

-	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC);
+	retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_dual_it_dtor, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC);
 	retval.handlers = &spl_handlers_dual_it;
 	return retval;
 }
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to