macOS: Add suport for Apple hardened runtime.

Thanks to Peter Cawley. #1334
This commit is contained in:
Mike Pall 2025-03-09 20:45:22 +01:00
parent f14556234c
commit 0254770582
2 changed files with 35 additions and 3 deletions

View File

@ -262,6 +262,14 @@ static void *callback_mcode_init(global_State *g, uint32_t *page)
#define CCPROT_CREATE 0 #define CCPROT_CREATE 0
#endif #endif
/* Check for macOS hardened runtime. */
#if LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000
#include <pthread.h>
#define CCMAP_CREATE MAP_JIT
#else
#define CCMAP_CREATE 0
#endif
#endif #endif
/* Allocate and initialize area for callback function pointers. */ /* Allocate and initialize area for callback function pointers. */
@ -276,10 +284,13 @@ static void callback_mcode_new(CTState *cts)
if (!p) if (!p)
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
#elif LJ_TARGET_POSIX #elif LJ_TARGET_POSIX
p = mmap(NULL, sz, (PROT_READ|PROT_WRITE|CCPROT_CREATE), MAP_PRIVATE|MAP_ANONYMOUS, p = mmap(NULL, sz, PROT_READ|PROT_WRITE|CCPROT_CREATE,
-1, 0); MAP_PRIVATE|MAP_ANONYMOUS|CCMAP_CREATE, -1, 0);
if (p == MAP_FAILED) if (p == MAP_FAILED)
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
#if CCMAP_CREATE
pthread_jit_write_protect_np(0);
#endif
#else #else
/* Fallback allocator. Fails if memory is not executable by default. */ /* Fallback allocator. Fails if memory is not executable by default. */
p = lj_mem_new(cts->L, sz); 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); LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot);
} }
#elif LJ_TARGET_POSIX #elif LJ_TARGET_POSIX
#if CCMAP_CREATE
pthread_jit_write_protect_np(1);
#else
mprotect(p, sz, (PROT_READ|PROT_EXEC)); mprotect(p, sz, (PROT_READ|PROT_EXEC));
#endif #endif
#endif
} }
/* Free area for callback function pointers. */ /* Free area for callback function pointers. */

View File

@ -98,6 +98,14 @@ static int mcode_setprot(void *p, size_t sz, DWORD prot)
#define MAP_ANONYMOUS MAP_ANON #define MAP_ANONYMOUS MAP_ANON
#endif #endif
/* Check for macOS hardened runtime. */
#if LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000
#include <pthread.h>
#define MCMAP_CREATE MAP_JIT
#else
#define MCMAP_CREATE 0
#endif
#define MCPROT_RW (PROT_READ|PROT_WRITE) #define MCPROT_RW (PROT_READ|PROT_WRITE)
#define MCPROT_RX (PROT_READ|PROT_EXEC) #define MCPROT_RX (PROT_READ|PROT_EXEC)
#define MCPROT_RWX (PROT_READ|PROT_WRITE|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) 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 (p == MAP_FAILED) {
if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL); if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL);
p = NULL; p = NULL;
#if MCMAP_CREATE
} else {
pthread_jit_write_protect_np(0);
#endif
} }
return p; 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) 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); return mprotect(p, sz, prot);
#endif
} }
#else #else