#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 <pthread.h>
+#define CCMAP_CREATE MAP_JIT
+#else
+#define CCMAP_CREATE 0
+#endif
+
#endif
/* Allocate and initialize area for callback function pointers. */
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);
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. */
#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 <pthread.h>
+#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)
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;
}
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