Skip to content

Fix default_object_handlers pointing to invalid memory with file_cache #9596

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Zend/zend_enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ jobs:
parameters:
configurationName: I386_DEBUG_ZTS
configurationParameters: '--enable-debug --enable-zts'
- template: azure/opcache_variation_job.yml
parameters:
configurationName: DEBUG_NTS_OPCACHE
configurationParameters: '--enable-debug --disable-zts'
timeoutInMinutes: 120
- ${{ if eq(variables['Build.Reason'], 'Schedule') }}:
- template: azure/i386/job.yml
parameters:
Expand All @@ -59,11 +64,6 @@ jobs:
--enable-debug --enable-zts --enable-address-sanitizer --enable-undefined-sanitizer
CFLAGS='-fno-sanitize-recover'
timeoutInMinutes: 90
- template: azure/opcache_variation_job.yml
parameters:
configurationName: DEBUG_NTS_OPCACHE
configurationParameters: '--enable-debug --disable-zts'
timeoutInMinutes: 120
- template: azure/job.yml
parameters:
configurationName: DEBUG_NTS_REPEAT
Expand Down
5 changes: 5 additions & 0 deletions ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down