From 53dbb760dad2c976347a9c093baee0e253b98731 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 10 Oct 2023 18:47:58 +0200 Subject: [PATCH] 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 --- NEWS | 2 ++ Zend/tests/gh12366.inc | 7 +++++++ Zend/tests/gh12366.phpt | 16 ++++++++++++++++ Zend/zend_enum.c | 2 ++ 4 files changed, 27 insertions(+) create mode 100644 Zend/tests/gh12366.inc create mode 100644 Zend/tests/gh12366.phpt diff --git a/NEWS b/NEWS index 20afa169cbd..60dbe770c07 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/Zend/tests/gh12366.inc b/Zend/tests/gh12366.inc new file mode 100644 index 00000000000..c0f64e14ba7 --- /dev/null +++ b/Zend/tests/gh12366.inc @@ -0,0 +1,7 @@ + +--EXPECT-- +enum(Level::Debug) diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 25261cf53f8..f807c819654 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -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();