Skip to content

Commit 53dbb76

Browse files
committedOct 11, 2023
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. Fixes GH-12366 Closes GH-12405
1 parent 310b528 commit 53dbb76

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed
 

‎NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.13
44

5+
- Core:
6+
. Fixed double-free of non-interned enum case name. (ilutov)
57

68
26 Oct 2023, PHP 8.2.12
79

‎Zend/tests/gh12366.inc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
enum Level: int {
4+
case Debug = 100;
5+
}
6+
7+
var_dump(Level::Debug);

‎Zend/tests/gh12366.phpt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
$file = __DIR__ . '/gh12366.inc';
11+
// Update timestamp and use opcache.file_update_protection=1 to prevent included file from being persisted in shm.
12+
touch($file);
13+
require $file;
14+
?>
15+
--EXPECT--
16+
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)