diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 192d0eca991..3e455b702cb 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -34,8 +34,7 @@ ZEND_API zend_class_entry *zend_ce_unit_enum; ZEND_API zend_class_entry *zend_ce_backed_enum; - -static zend_object_handlers enum_handlers; +ZEND_API zend_object_handlers zend_enum_object_handlers; zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv) { @@ -157,9 +156,9 @@ void zend_register_enum_ce(void) zend_ce_backed_enum = register_class_BackedEnum(zend_ce_unit_enum); zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum; - memcpy(&enum_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - enum_handlers.clone_obj = NULL; - enum_handlers.compare = zend_objects_not_comparable; + memcpy(&zend_enum_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + zend_enum_object_handlers.clone_obj = NULL; + zend_enum_object_handlers.compare = zend_objects_not_comparable; } void zend_enum_add_interfaces(zend_class_entry *ce) @@ -183,7 +182,7 @@ void zend_enum_add_interfaces(zend_class_entry *ce) ce->interface_names[num_interfaces_before + 1].lc_name = zend_string_init("backedenum", sizeof("backedenum") - 1, 0); } - ce->default_object_handlers = &enum_handlers; + ce->default_object_handlers = &zend_enum_object_handlers; } zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce) diff --git a/Zend/zend_enum.h b/Zend/zend_enum.h index 797eb0c8ab5..dbb230c4175 100644 --- a/Zend/zend_enum.h +++ b/Zend/zend_enum.h @@ -26,6 +26,7 @@ BEGIN_EXTERN_C() extern ZEND_API zend_class_entry *zend_ce_unit_enum; extern ZEND_API zend_class_entry *zend_ce_backed_enum; +extern ZEND_API zend_object_handlers zend_enum_object_handlers; void zend_register_enum_ce(void); void zend_enum_add_interfaces(zend_class_entry *ce); diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index a15736b72e5..1cd639403f6 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -23,6 +23,7 @@ #include "zend_interfaces.h" #include "zend_attributes.h" #include "zend_system_id.h" +#include "zend_enum.h" #include "php.h" #ifdef ZEND_WIN32 @@ -1714,6 +1715,10 @@ static void zend_file_cache_unserialize_class(zval *zv, ZEND_MAP_PTR_INIT(ce->mutable_data, NULL); ZEND_MAP_PTR_INIT(ce->static_members_table, NULL); } + + // Memory addresses of object handlers are not stable. They can change due to ASLR or order of linking dynamic. To + // avoid pointing to invalid memory we relink default_object_handlers here. + ce->default_object_handlers = ce->ce_flags & ZEND_ACC_ENUM ? &zend_enum_object_handlers : &std_object_handlers; } static void zend_file_cache_unserialize_warnings(zend_persistent_script *script, void *buf)