Skip to content

Commit 3daa8a9

Browse files
committed
Fix default_object_handlers pointing to invalid memory with file_cache
Closes GH-9596
1 parent d10a04b commit 3daa8a9

File tree

3 files changed

+11
-6
lines changed

3 files changed

+11
-6
lines changed

Zend/zend_enum.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434

3535
ZEND_API zend_class_entry *zend_ce_unit_enum;
3636
ZEND_API zend_class_entry *zend_ce_backed_enum;
37-
38-
static zend_object_handlers enum_handlers;
37+
ZEND_API zend_object_handlers zend_enum_object_handlers;
3938

4039
zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv)
4140
{
@@ -157,9 +156,9 @@ void zend_register_enum_ce(void)
157156
zend_ce_backed_enum = register_class_BackedEnum(zend_ce_unit_enum);
158157
zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum;
159158

160-
memcpy(&enum_handlers, &std_object_handlers, sizeof(zend_object_handlers));
161-
enum_handlers.clone_obj = NULL;
162-
enum_handlers.compare = zend_objects_not_comparable;
159+
memcpy(&zend_enum_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
160+
zend_enum_object_handlers.clone_obj = NULL;
161+
zend_enum_object_handlers.compare = zend_objects_not_comparable;
163162
}
164163

165164
void zend_enum_add_interfaces(zend_class_entry *ce)
@@ -183,7 +182,7 @@ void zend_enum_add_interfaces(zend_class_entry *ce)
183182
ce->interface_names[num_interfaces_before + 1].lc_name = zend_string_init("backedenum", sizeof("backedenum") - 1, 0);
184183
}
185184

186-
ce->default_object_handlers = &enum_handlers;
185+
ce->default_object_handlers = &zend_enum_object_handlers;
187186
}
188187

189188
zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce)

Zend/zend_enum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ BEGIN_EXTERN_C()
2626

2727
extern ZEND_API zend_class_entry *zend_ce_unit_enum;
2828
extern ZEND_API zend_class_entry *zend_ce_backed_enum;
29+
extern ZEND_API zend_object_handlers zend_enum_object_handlers;
2930

3031
void zend_register_enum_ce(void);
3132
void zend_enum_add_interfaces(zend_class_entry *ce);

ext/opcache/zend_file_cache.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "zend_interfaces.h"
2424
#include "zend_attributes.h"
2525
#include "zend_system_id.h"
26+
#include "zend_enum.h"
2627

2728
#include "php.h"
2829
#ifdef ZEND_WIN32
@@ -1714,6 +1715,10 @@ static void zend_file_cache_unserialize_class(zval *zv,
17141715
ZEND_MAP_PTR_INIT(ce->mutable_data, NULL);
17151716
ZEND_MAP_PTR_INIT(ce->static_members_table, NULL);
17161717
}
1718+
1719+
// Memory addresses of object handlers are not stable. They can change due to ASLR or order of linking dynamic. To
1720+
// avoid pointing to invalid memory we relink default_object_handlers here.
1721+
ce->default_object_handlers = ce->ce_flags & ZEND_ACC_ENUM ? &zend_enum_object_handlers : &std_object_handlers;
17171722
}
17181723

17191724
static void zend_file_cache_unserialize_warnings(zend_persistent_script *script, void *buf)

0 commit comments

Comments
 (0)