From c70f21767588c9b28871c917d156d8fc6a320ad6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 13 Jan 2025 13:46:59 +0000 Subject: [PATCH] prepare: don't bother making another property info copy if it already exists fo classes that were unlinked during first copy, we might've already copied the relevant property info to the destination thread. In this case in the past, this would just silently fail to insert the updated property info and go on to free it. We probably ought to get rid of the old property_info and replace it with the newly copied version, but for now this restores the original behaviour, which seemed to work anyway??? However, possible that this may break with property hooks inheritance. Needs further testing. --- src/prepare.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/prepare.c b/src/prepare.c index 25c561b..847d793 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -255,10 +255,15 @@ static void prepare_class_property_table(const pmmpthread_ident_t* source, zend_ zend_property_info *info; zend_string *name; ZEND_HASH_FOREACH_STR_KEY_PTR(&candidate->properties_info, name, info) { - zend_property_info* dup = copy_property_info(source, candidate, prepared, info); - if (!zend_hash_str_add_ptr(&prepared->properties_info, name->val, name->len, dup)) { - if (dup->doc_comment) - zend_string_release(dup->doc_comment); + zend_property_info* dup = zend_hash_find_ptr(&prepared->properties_info, name); + //TODO: if this is non-null it may need updating (if we copied it previously for an unlinked class) + //for now this just ensures that we don't have UAFs with reused property infos + //hopefully this doesn't shit a brick??? + if (dup == NULL) { + dup = copy_property_info(source, candidate, prepared, info); + if (!zend_hash_str_add_ptr(&prepared->properties_info, name->val, name->len, dup)) { + ZEND_ASSERT(0); + } } } ZEND_HASH_FOREACH_END();