From 21d906e838856715d7f1c0def74e642f68a44728 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 25 Oct 2024 19:45:13 +0200 Subject: [PATCH] Fix GH-16588: UAF in Observer->serialize --- ext/spl/spl_observer.c | 9 ++++++++- ext/spl/tests/gh16588.phpt | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/gh16588.phpt diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index cc2956ccc27ea..d3b58f0d762ee 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -797,11 +797,18 @@ PHP_METHOD(SplObjectStorage, serialize) RETURN_NULL(); } ZVAL_OBJ(&obj, element->obj); + + /* Protect against modification; we need a full copy because the data may be refcounted. */ + zval inf_copy; + ZVAL_COPY(&inf_copy, &element->inf); + php_var_serialize(&buf, &obj, &var_hash); smart_str_appendc(&buf, ','); - php_var_serialize(&buf, &element->inf, &var_hash); + php_var_serialize(&buf, &inf_copy, &var_hash); smart_str_appendc(&buf, ';'); zend_hash_move_forward_ex(&intern->storage, &pos); + + zval_ptr_dtor(&inf_copy); } /* members */ diff --git a/ext/spl/tests/gh16588.phpt b/ext/spl/tests/gh16588.phpt new file mode 100644 index 0000000000000..6cf668716ac32 --- /dev/null +++ b/ext/spl/tests/gh16588.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16588 (UAF in Observer->serialize) +--CREDITS-- +chibinz +--FILE-- +removeAll($store); + return []; + } +} + +$store = new SplObjectStorage; +$store[new C] = new stdClass; +var_dump($store->serialize()); + +?> +--EXPECT-- +string(47) "x:i:1;O:1:"C":0:{},O:8:"stdClass":0:{};m:a:0:{}"