Skip to content

Commit bdc87b0

Browse files
committed
Fix #80092: ZTS + preload = segfault on shutdown
After preloading has executed, the executor globals for class_table and function_table are still referring to the values during preloading. If no request happens after that then these values will remain dangling pointers. If then the -v option on CLI or -h option (and possibly others) on CGI is provided, there is a double free. Fix it by nulling the pointers explicitly after preloading has finished to fix it for all SAPIs. Closes GH-12311.
1 parent a1225f3 commit bdc87b0

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PHP NEWS
88
. Fixed bug GH-12215 (Module entry being overwritten causes type errors in
99
ext/dom). (nielsdos)
1010
. Fixed bug GH-12273 (__builtin_cpu_init check). (Freaky)
11+
. Fixed bug #80092 (ZTS + preload = segfault on shutdown). (nielsdos)
1112

1213
- CType:
1314
. Fixed bug GH-11997 (ctype_alnum 5 times slower in PHP 8.1 or greater).

ext/opcache/ZendAccelerator.c

+2
Original file line numberDiff line numberDiff line change
@@ -4780,6 +4780,8 @@ static int accel_finish_startup(void)
47804780
SIGG(check) = 0;
47814781
#endif
47824782
php_request_shutdown(NULL); /* calls zend_shared_alloc_unlock(); */
4783+
EG(class_table) = NULL;
4784+
EG(function_table) = NULL;
47834785
PG(report_memleaks) = orig_report_memleaks;
47844786
} else {
47854787
zend_shared_alloc_unlock();

sapi/cli/tests/bug80092.phpt

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Bug #80092 (ZTS + preload = segfault on shutdown)
3+
--SKIPIF--
4+
<?php
5+
include 'skipif.inc';
6+
if (substr(PHP_OS, 0, 3) == 'WIN') {
7+
die ("skip not for Windows");
8+
}
9+
$extDir = ini_get('extension_dir');
10+
if (!file_exists($extDir . '/opcache.so')) {
11+
die ('skip opcache shared object not found in extension_dir');
12+
}
13+
?>
14+
--FILE--
15+
<?php
16+
17+
$cmd = [
18+
PHP_BINARY, '-n',
19+
'-dextension_dir=' . ini_get('extension_dir'),
20+
'-dzend_extension=opcache.so',
21+
'-dopcache.enable=1',
22+
'-dopcache.enable_cli=1',
23+
'-dopcache.preload=' . __DIR__ . '/preload.inc',
24+
'-v'
25+
];
26+
27+
$proc = proc_open($cmd, [['null'], ['pipe', 'w'], ['redirect', 1]], $pipes);
28+
echo stream_get_contents($pipes[1]);
29+
30+
?>
31+
--EXPECTF--
32+
preloaded
33+
PHP %s
34+
Copyright (c) The PHP Group
35+
Zend Engine %s
36+
with Zend OPcache %s

sapi/cli/tests/preload.inc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
class SomeClass {}
4+
5+
function foo() {}
6+
7+
echo "preloaded\n";

0 commit comments

Comments
 (0)