From ad788dec1f2836cbd3a7e77e98427aaabebb8f3b 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. --- Zend/tests/gh12366.inc | 7 +++++++ Zend/tests/gh12366.phpt | 16 ++++++++++++++++ Zend/zend_enum.c | 2 ++ 3 files changed, 25 insertions(+) create mode 100644 Zend/tests/gh12366.inc create mode 100644 Zend/tests/gh12366.phpt diff --git a/Zend/tests/gh12366.inc b/Zend/tests/gh12366.inc new file mode 100644 index 0000000000000..c0f64e14ba7b5 --- /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 25261cf53f880..f807c8196548e 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();