mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix GH-20352: UAF in php_output_handler_free via re-entrant ob_start() during error deactivation
This commit is contained in:
2
NEWS
2
NEWS
@@ -8,6 +8,8 @@ PHP NEWS
|
||||
. Fixed bug GH-20695 (Assertion failure in normalize_value() when parsing
|
||||
malformed INI input via parse_ini_string()). (ndossche)
|
||||
. Fixed bug GH-20714 (Uncatchable exception thrown in generator). (ilutov)
|
||||
. Fixed bug GH-20352 (UAF in php_output_handler_free via re-entrant
|
||||
ob_start() during error deactivation). (ndossche)
|
||||
|
||||
- DOM:
|
||||
. Fixed bug GH-20722 (Null pointer dereference in DOM namespace node cloning
|
||||
|
||||
@@ -187,8 +187,12 @@ PHPAPI void php_output_deactivate(void)
|
||||
/* release all output handlers */
|
||||
if (OG(handlers).elements) {
|
||||
while ((handler = zend_stack_top(&OG(handlers)))) {
|
||||
php_output_handler_free(handler);
|
||||
zend_stack_del_top(&OG(handlers));
|
||||
/* It's possible to start a new output handler and mark it as active,
|
||||
* however this loop will destroy all active handlers. */
|
||||
OG(active) = NULL;
|
||||
ZEND_ASSERT(OG(running) == NULL && "output is deactivated therefore running should stay NULL");
|
||||
php_output_handler_free(handler);
|
||||
}
|
||||
}
|
||||
zend_stack_destroy(&OG(handlers));
|
||||
@@ -718,10 +722,11 @@ PHPAPI void php_output_handler_dtor(php_output_handler *handler)
|
||||
* Destroy and free an output handler */
|
||||
PHPAPI void php_output_handler_free(php_output_handler **h)
|
||||
{
|
||||
if (*h) {
|
||||
php_output_handler_dtor(*h);
|
||||
efree(*h);
|
||||
php_output_handler *handler = *h;
|
||||
if (handler) {
|
||||
*h = NULL;
|
||||
php_output_handler_dtor(handler);
|
||||
efree(handler);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
24
tests/output/gh20352.phpt
Normal file
24
tests/output/gh20352.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
GH-20352 (UAF in php_output_handler_free via re-entrant ob_start() during error deactivation)
|
||||
--FILE--
|
||||
<?php
|
||||
class Test {
|
||||
public function __destruct() {
|
||||
// Spray output stack
|
||||
for ($i = 0; $i < 1000; $i++)
|
||||
ob_start(static function() {});
|
||||
}
|
||||
|
||||
public function __invoke($x) {
|
||||
// Trigger php_output_deactivate() through forbidden operation
|
||||
ob_start('foo');
|
||||
return $x;
|
||||
}
|
||||
}
|
||||
|
||||
ob_start(new Test, 1);
|
||||
|
||||
echo "trigger bug";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: ob_start(): Cannot use output buffering in output buffering display handlers in %s on line %d
|
||||
Reference in New Issue
Block a user