mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-18033: NULL-ptr dereference when using register_tick_function in destructor
The problem is that `php_request_shutdown` calls `php_deactivate_ticks` prior to running destructors and the shutdown functions and finalizing output handlers. So if a destructor or shutdown function re-registers a tick function, then the user tick functions handler will be added back to `PG(tick_functions)`. When the next request happens, the list `PG(tick_functions)` still contains an entry to call the user tick functions (added in the previous request during shutdown). This causes a NULL deref eventually because `run_user_tick_functions` assumes that if it is called then `BG(user_tick_functions)` must be non-NULL. Fix this by moving the tick handler deactivation. Closes GH-18047.
This commit is contained in:
2
NEWS
2
NEWS
@@ -33,6 +33,8 @@ PHP NEWS
|
||||
zend.exception_string_param_max_len=0. (timwolla)
|
||||
. Fixed bug GH-17959 (Relax missing trait fatal error to error exception).
|
||||
(ilutov)
|
||||
. Fixed bug GH-18033 (NULL-ptr dereference when using register_tick_function
|
||||
in destructor). (nielsdos)
|
||||
|
||||
- Curl:
|
||||
. Added curl_multi_get_handles(). (timwolla)
|
||||
|
||||
@@ -38,6 +38,9 @@ PHP 8.5 UPGRADE NOTES
|
||||
resources that were indirectly collected through cycles.
|
||||
. It is now allowed to substitute static with self or the concrete class name
|
||||
in final subclasses.
|
||||
. The tick handlers are now deactivated after all shutdown functions, destructors
|
||||
have run and the output handlers have been cleaned up.
|
||||
This is a consequence of fixing GH-18033.
|
||||
|
||||
- Intl:
|
||||
. The extension now requires at least ICU 57.1.
|
||||
|
||||
24
Zend/tests/declare/gh18033_1.phpt
Normal file
24
Zend/tests/declare/gh18033_1.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
GH-18033 (NULL-ptr dereference when using register_tick_function in destructor)
|
||||
--DESCRIPTION--
|
||||
Needs --repeat 2 or something similar to reproduce
|
||||
--CREDITS--
|
||||
clesmian
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __destruct() {
|
||||
declare(ticks=1);
|
||||
register_tick_function(
|
||||
function() { }
|
||||
);
|
||||
echo "In destructor\n";
|
||||
}
|
||||
}
|
||||
|
||||
$bar = new Foo;
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
In destructor
|
||||
16
Zend/tests/declare/gh18033_2.phpt
Normal file
16
Zend/tests/declare/gh18033_2.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
GH-18033 (NULL-ptr dereference when using register_tick_function in ob_start)
|
||||
--DESCRIPTION--
|
||||
Needs --repeat 2 or something similar to reproduce
|
||||
--CREDITS--
|
||||
clesmian
|
||||
--FILE--
|
||||
<?php
|
||||
ob_start(function() {
|
||||
declare(ticks=1);
|
||||
register_tick_function(
|
||||
function() { }
|
||||
);
|
||||
});
|
||||
?>
|
||||
--EXPECT--
|
||||
@@ -1904,8 +1904,6 @@ void php_request_shutdown(void *dummy)
|
||||
*/
|
||||
EG(current_execute_data) = NULL;
|
||||
|
||||
php_deactivate_ticks();
|
||||
|
||||
/* 0. Call any open observer end handlers that are still open after a zend_bailout */
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
zend_observer_fcall_end_all();
|
||||
@@ -1926,6 +1924,8 @@ void php_request_shutdown(void *dummy)
|
||||
php_output_end_all();
|
||||
} zend_end_try();
|
||||
|
||||
php_deactivate_ticks();
|
||||
|
||||
/* 4. Reset max_execution_time (no longer executing php code after response sent) */
|
||||
zend_try {
|
||||
zend_unset_timeout();
|
||||
|
||||
Reference in New Issue
Block a user