Skip to content

Commit 9ef7a2d

Browse files
committed
Fix use-after-free of constant name
The constant name is usually interend. Without opcache, compilation always interns strings. Without opcache, compilation does not intern (new) strings, but persisting of script does. If a script is not stored in shm the constant name will not be interned. The building of enum backing stores was missing a addref for the constant name, leading to a double-free when releasing constants and backing stores of enums.
1 parent bb046c7 commit 9ef7a2d

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

Zend/tests/gh12366.phpt

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-12366: Use-after-free of constant name when script doesn't fit in SHM
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable_cli=1
7+
opcache.file_update_protection=1
8+
--FILE--
9+
<?php
10+
11+
$file = __DIR__ . '/gh12366.inc';
12+
13+
$fileContent = <<<PHP
14+
<?php
15+
enum Level: int {
16+
case Debug = 100;
17+
}
18+
var_dump(Level::Debug);
19+
PHP;
20+
file_put_contents($file, $fileContent);
21+
22+
// Use opcache.file_update_protection=1 to make sure the included file is not persisted in shm.
23+
require $file;
24+
25+
?>
26+
--CLEAN--
27+
<?php
28+
$file = __DIR__ . '/gh12366.inc';
29+
@unlink($file);
30+
?>
31+
--EXPECT--
32+
enum(Level::Debug)

Zend/zend_enum.c

+2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce)
229229
ZSTR_VAL(name));
230230
goto failure;
231231
}
232+
Z_TRY_ADDREF_P(case_name);
232233
zend_hash_index_add_new(backed_enum_table, long_key, case_name);
233234
} else {
234235
ZEND_ASSERT(ce->enum_backing_type == IS_STRING);
@@ -241,6 +242,7 @@ zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce)
241242
ZSTR_VAL(name));
242243
goto failure;
243244
}
245+
Z_TRY_ADDREF_P(case_name);
244246
zend_hash_add_new(backed_enum_table, string_key, case_name);
245247
}
246248
} ZEND_HASH_FOREACH_END();

0 commit comments

Comments
 (0)