Fix use-after-free in property coercion with __toString()

This was only partially fixed in PHP-8.3. Backports and fixes the case for both
initialized and uninitialized property writes.

Fixes GH-14969
Closes GH-14971
This commit is contained in:
Ilija Tovilo 2024-07-16 11:55:55 +02:00
parent 6d0db52896
commit 8c312ba74b
No known key found for this signature in database
GPG Key ID: 5050C66BFCD1015A
3 changed files with 51 additions and 2 deletions

2
NEWS
View File

@ -10,6 +10,8 @@ PHP NEWS
(nielsdos)
. Fixed OSS-Fuzz #69765. (nielsdos)
. Fixed bug GH-14741 (Segmentation fault in Zend/zend_types.h). (nielsdos)
. Fixed bug GH-14969 (Use-after-free in property coercion with __toString()).
(ilutov)
- Dom:
. Fixed bug GH-14702 (DOMDocument::xinclude() crash). (nielsdos)

47
Zend/tests/gh14969.phpt Normal file
View File

@ -0,0 +1,47 @@
--TEST--
GH-14969: Crash on coercion with throwing __toString()
--FILE--
<?php
class C {
public function __toString() {
global $c;
$c = [];
throw new Exception(__METHOD__);
}
}
class D {
public string $prop;
}
$c = new C();
$d = new D();
try {
$d->prop = $c;
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
var_dump($d);
$c = new C();
$d->prop = 'foo';
try {
$d->prop = $c;
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
var_dump($d);
?>
--EXPECTF--
C::__toString
object(D)#%d (0) {
["prop"]=>
uninitialized(string)
}
C::__toString
object(D)#2 (1) {
["prop"]=>
string(3) "foo"
}

View File

@ -819,7 +819,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva
ZVAL_COPY_VALUE(&tmp, value);
if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) {
Z_TRY_DELREF_P(value);
zval_ptr_dtor(&tmp);
variable_ptr = &EG(error_zval);
goto exit;
}
@ -890,7 +890,7 @@ write_std_property:
ZVAL_COPY_VALUE(&tmp, value);
if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) {
zval_ptr_dtor(value);
zval_ptr_dtor(&tmp);
goto exit;
}
value = &tmp;