Skip to content

Commit 93d2776

Browse files
committed
Fix GH-12232: FPM: segfault dynamically loading extension without opcache
1 parent 4f044e9 commit 93d2776

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

sapi/fpm/fpm/fpm_php.c

+2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */
8787

8888
if (!strcmp(name, "extension") && *value) {
8989
zval zv;
90+
zend_interned_strings_switch_storage(0);
9091
php_dl(value, MODULE_PERSISTENT, &zv, 1);
92+
zend_interned_strings_switch_storage(1);
9193
return Z_TYPE(zv) == IS_TRUE;
9294
}
9395

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
FPM: gh12232 - loading shared ext in FPM config
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
FPM\Tester::skipIfSharedExtensionNotFound('gnupg');
7+
?>
8+
--FILE--
9+
<?php
10+
11+
require_once "tester.inc";
12+
13+
$cfg = <<<EOT
14+
[global]
15+
error_log = {{FILE:LOG}}
16+
[unconfined]
17+
listen = {{ADDR}}
18+
pm = static
19+
pm.max_children = 1
20+
pm.status_path = /status
21+
catch_workers_output = yes
22+
php_admin_value[extension] = gnupg
23+
EOT;
24+
25+
$code = <<<EOT
26+
<?php
27+
var_dump(extension_loaded('gnupg'));
28+
EOT;
29+
30+
$tester = new FPM\Tester($cfg, $code);
31+
$tester->start();
32+
$tester->expectLogStartNotices();
33+
$tester->request()->expectBody('bool(true)');
34+
$tester->terminate();
35+
$tester->expectLogTerminatingNotices();
36+
$tester->close();
37+
38+
?>
39+
Done
40+
--EXPECT--
41+
Done
42+
--CLEAN--
43+
<?php
44+
require_once "tester.inc";
45+
FPM\Tester::clean();
46+
?>
47+
<?php

sapi/fpm/tests/tester.inc

+11
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,17 @@ class Tester
319319
}
320320
}
321321

322+
/**
323+
* Skip if shared extension is not available in extension directory.
324+
*/
325+
static public function skipIfSharedExtensionNotFound($extensionName)
326+
{
327+
$soPath = ini_get('extension_dir') . '/' . $extensionName . '.so';
328+
if ( ! file_exists($soPath)) {
329+
die("skip $extensionName extension not present in extension_dir");
330+
}
331+
}
332+
322333
/**
323334
* Tester constructor.
324335
*

0 commit comments

Comments
 (0)