diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 52f92932..d93dbc64 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c @@ -262,6 +262,14 @@ static void *callback_mcode_init(global_State *g, uint32_t *page) #define CCPROT_CREATE 0 #endif +/* Check for macOS hardened runtime. */ +#if LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000 +#include +#define CCMAP_CREATE MAP_JIT +#else +#define CCMAP_CREATE 0 +#endif + #endif /* Allocate and initialize area for callback function pointers. */ @@ -276,10 +284,13 @@ static void callback_mcode_new(CTState *cts) if (!p) lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); #elif LJ_TARGET_POSIX - p = mmap(NULL, sz, (PROT_READ|PROT_WRITE|CCPROT_CREATE), MAP_PRIVATE|MAP_ANONYMOUS, - -1, 0); + p = mmap(NULL, sz, PROT_READ|PROT_WRITE|CCPROT_CREATE, + MAP_PRIVATE|MAP_ANONYMOUS|CCMAP_CREATE, -1, 0); if (p == MAP_FAILED) lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); +#if CCMAP_CREATE + pthread_jit_write_protect_np(0); +#endif #else /* Fallback allocator. Fails if memory is not executable by default. */ p = lj_mem_new(cts->L, sz); @@ -296,8 +307,12 @@ static void callback_mcode_new(CTState *cts) LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot); } #elif LJ_TARGET_POSIX +#if CCMAP_CREATE + pthread_jit_write_protect_np(1); +#else mprotect(p, sz, (PROT_READ|PROT_EXEC)); #endif +#endif } /* Free area for callback function pointers. */ diff --git a/src/lj_mcode.c b/src/lj_mcode.c index 864da7fb..43694226 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c @@ -98,6 +98,14 @@ static int mcode_setprot(void *p, size_t sz, DWORD prot) #define MAP_ANONYMOUS MAP_ANON #endif +/* Check for macOS hardened runtime. */ +#if LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000 +#include +#define MCMAP_CREATE MAP_JIT +#else +#define MCMAP_CREATE 0 +#endif + #define MCPROT_RW (PROT_READ|PROT_WRITE) #define MCPROT_RX (PROT_READ|PROT_EXEC) #define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC) @@ -109,10 +117,14 @@ static int mcode_setprot(void *p, size_t sz, DWORD prot) static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot) { - void *p = mmap((void *)hint, sz, prot|MCPROT_CREATE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + void *p = mmap((void *)hint, sz, prot|MCPROT_CREATE, MAP_PRIVATE|MAP_ANONYMOUS|MCMAP_CREATE, -1, 0); if (p == MAP_FAILED) { if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL); p = NULL; +#if MCMAP_CREATE + } else { + pthread_jit_write_protect_np(0); +#endif } return p; } @@ -125,7 +137,12 @@ static void mcode_free(jit_State *J, void *p, size_t sz) static int mcode_setprot(void *p, size_t sz, int prot) { +#if MCMAP_CREATE + pthread_jit_write_protect_np((prot & PROC_EXEC)); + return 0; +#else return mprotect(p, sz, prot); +#endif } #else