From 1f14b3fa92d4442a60233e9596ddec428a985e3c Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 3 Jun 2022 02:46:35 +0800 Subject: Ensure that VM_PROT_EXECUTE is set on the trampoline page. (#718) --- src/closures.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/closures.c b/src/closures.c index f7bead6..db7ec94 100644 --- a/src/closures.c +++ b/src/closures.c @@ -134,7 +134,7 @@ ffi_tramp_is_present (__attribute__((unused)) void *ptr) # define HAVE_MNTENT 1 # endif # if defined(_WIN32) || defined(__OS2__) -/* Windows systems may have Data Execution Protection (DEP) enabled, +/* Windows systems may have Data Execution Protection (DEP) enabled, which requires the use of VirtualMalloc/VirtualFree to alloc/free executable memory. */ # define FFI_MMAP_EXEC_WRIT 1 @@ -230,12 +230,24 @@ ffi_trampoline_table_alloc (void) kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0, VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template, FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE); - if (kt != KERN_SUCCESS || !(cur_prot & VM_PROT_EXECUTE)) + if (kt != KERN_SUCCESS) { vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2); return NULL; } + if (!(cur_prot & VM_PROT_EXECUTE)) + { + /* If VM_PROT_EXECUTE isn't set on the remapped trampoline page, set it */ + kt = vm_protect (mach_task_self (), trampoline_page, PAGE_MAX_SIZE, + FALSE, cur_prot | VM_PROT_EXECUTE); + if (kt != KERN_SUCCESS) + { + vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2); + return NULL; + } + } + /* We have valid trampoline and config pages */ table = calloc (1, sizeof (ffi_trampoline_table)); table->free_count = FFI_TRAMPOLINE_COUNT; -- cgit v1.2.1