1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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
This commit is contained in:
Ilija Tovilo
2023-10-10 18:47:58 +02:00
parent 310b5283eb
commit 53dbb760da
4 changed files with 27 additions and 0 deletions

2
NEWS
View File

@@ -2,6 +2,8 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.2.13
- Core:
. Fixed double-free of non-interned enum case name. (ilutov)
26 Oct 2023, PHP 8.2.12

7
Zend/tests/gh12366.inc Normal file
View File

@@ -0,0 +1,7 @@
<?php
enum Level: int {
case Debug = 100;
}
var_dump(Level::Debug);

16
Zend/tests/gh12366.phpt Normal file
View File

@@ -0,0 +1,16 @@
--TEST--
GH-12366: Use-after-free of constant name when script doesn't fit in SHM
--EXTENSIONS--
opcache
--INI--
opcache.enable_cli=1
opcache.file_update_protection=1
--FILE--
<?php
$file = __DIR__ . '/gh12366.inc';
// Update timestamp and use opcache.file_update_protection=1 to prevent included file from being persisted in shm.
touch($file);
require $file;
?>
--EXPECT--
enum(Level::Debug)

View File

@@ -229,6 +229,7 @@ zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce)
ZSTR_VAL(name));
goto failure;
}
Z_TRY_ADDREF_P(case_name);
zend_hash_index_add_new(backed_enum_table, long_key, case_name);
} else {
ZEND_ASSERT(ce->enum_backing_type == IS_STRING);
@@ -241,6 +242,7 @@ zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce)
ZSTR_VAL(name));
goto failure;
}
Z_TRY_ADDREF_P(case_name);
zend_hash_add_new(backed_enum_table, string_key, case_name);
}
} ZEND_HASH_FOREACH_END();