diff --git a/Zend/tests/gh11734.phpt b/Zend/tests/gh11734.phpt new file mode 100644 index 0000000000000..58d2ec59ad347 --- /dev/null +++ b/Zend/tests/gh11734.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-11734: Use-of-uninitialized-value when OOM on object allocation +--INI-- +memory_limit=2M +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted at %s (tried to allocate %d bytes) in %s on line %d diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 7a9a3a00082c0..85c6cf2c2bf1a 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -91,6 +91,11 @@ static zend_always_inline size_t zend_object_properties_size(zend_class_entry *c static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_entry *ce) { void *obj = emalloc(obj_size + zend_object_properties_size(ce)); memset(obj, 0, obj_size - sizeof(zend_object)); + /* Set to std_object_handlers in case there is an OOM error before any other handlers are + * installed. This avoids a use-of-uninitialized-value on shutdown. This would be more fitting in + * zend_object_std_init(), but some extensions set handlers before calling + * zend_object_std_init(). */ + ((zend_object *)((uintptr_t)obj + obj_size - sizeof(zend_object)))->handlers = &std_object_handlers; return obj; }