summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-10-24 15:19:03 +0200
committerMike Pall <mike>2013-10-24 15:19:03 +0200
commit7e538b5f0ae1dfa7667f3a974d570f0cd8190aca (patch)
treeb49722230d9e608d2071bba20bbc2e9bbd919f3b
parent4fba08a9aca4ce99a6a51f5faca2e1e091ad1422 (diff)
downloadluajit2-7e538b5f0ae1dfa7667f3a974d570f0cd8190aca.tar.gz
Check for failure to mark memory as executable (restricted kernels).
-rw-r--r--src/Makefile.dep8
-rw-r--r--src/lj_errmsg.h1
-rw-r--r--src/lj_mcode.c35
3 files changed, 29 insertions, 15 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index 5d91723a..8ca33151 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -17,8 +17,8 @@ lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
- lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_ff.h lj_ffdef.h \
- lj_lib.h lj_libdef.h
+ lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_ff.h \
+ lj_ffdef.h lj_lib.h lj_libdef.h
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
@@ -129,8 +129,8 @@ lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \
- lj_traceerr.h lj_vm.h
+ lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \
+ lj_dispatch.h lj_bc.h lj_traceerr.h lj_vm.h
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_vm.h lj_strscan.h
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h
index fd46acd4..8f3f5198 100644
--- a/src/lj_errmsg.h
+++ b/src/lj_errmsg.h
@@ -102,6 +102,7 @@ ERRDEF(STRFMTW, "invalid format (width or precision too long)")
ERRDEF(STRGSRV, "invalid replacement value (a %s)")
ERRDEF(BADMODN, "name conflict for module " LUA_QS)
#if LJ_HASJIT
+ERRDEF(JITPROT, "runtime code generation failed, restricted kernel?")
#if LJ_TARGET_X86ORX64
ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2")
#else
diff --git a/src/lj_mcode.c b/src/lj_mcode.c
index cb79e8cd..d464802b 100644
--- a/src/lj_mcode.c
+++ b/src/lj_mcode.c
@@ -9,6 +9,7 @@
#include "lj_obj.h"
#if LJ_HASJIT
#include "lj_gc.h"
+#include "lj_err.h"
#include "lj_jit.h"
#include "lj_mcode.h"
#include "lj_trace.h"
@@ -78,10 +79,10 @@ static void mcode_free(jit_State *J, void *p, size_t sz)
VirtualFree(p, 0, MEM_RELEASE);
}
-static void mcode_setprot(void *p, size_t sz, DWORD prot)
+static int mcode_setprot(void *p, size_t sz, DWORD prot)
{
DWORD oprot;
- VirtualProtect(p, sz, prot, &oprot);
+ return !VirtualProtect(p, sz, prot, &oprot);
}
#elif LJ_TARGET_POSIX
@@ -112,9 +113,9 @@ static void mcode_free(jit_State *J, void *p, size_t sz)
munmap(p, sz);
}
-static void mcode_setprot(void *p, size_t sz, int prot)
+static int mcode_setprot(void *p, size_t sz, int prot)
{
- mprotect(p, sz, prot);
+ return mprotect(p, sz, prot);
}
#elif LJ_64
@@ -140,8 +141,6 @@ static void mcode_free(jit_State *J, void *p, size_t sz)
lj_mem_free(J2G(J), p, sz);
}
-#define mcode_setprot(p, sz, prot) UNUSED(p)
-
#endif
/* -- MCode area protection ----------------------------------------------- */
@@ -180,11 +179,23 @@ static void mcode_protect(jit_State *J, int prot)
#define MCPROT_GEN MCPROT_RW
#define MCPROT_RUN MCPROT_RX
+/* Protection twiddling failed. Probably due to kernel security. */
+static LJ_NOINLINE void mcode_protfail(jit_State *J)
+{
+ lua_CFunction panic = J2G(J)->panic;
+ if (panic) {
+ lua_State *L = J->L;
+ setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITPROT));
+ panic(L);
+ }
+}
+
/* Change protection of MCode area. */
static void mcode_protect(jit_State *J, int prot)
{
if (J->mcprot != prot) {
- mcode_setprot(J->mcarea, J->szmcarea, prot);
+ if (LJ_UNLIKELY(mcode_setprot(J->mcarea, J->szmcarea, prot)))
+ mcode_protfail(J);
J->mcprot = prot;
}
}
@@ -305,7 +316,8 @@ void lj_mcode_commit(jit_State *J, MCode *top)
/* Abort the reservation. */
void lj_mcode_abort(jit_State *J)
{
- mcode_protect(J, MCPROT_RUN);
+ if (J->mcarea)
+ mcode_protect(J, MCPROT_RUN);
}
/* Set/reset protection to allow patching of MCode areas. */
@@ -318,8 +330,8 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish)
if (finish) {
if (J->mcarea == ptr)
mcode_protect(J, MCPROT_RUN);
- else
- mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN);
+ else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN)))
+ mcode_protfail(J);
return NULL;
} else {
MCode *mc = J->mcarea;
@@ -333,7 +345,8 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish)
mc = ((MCLink *)mc)->next;
lua_assert(mc != NULL);
if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) {
- mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN);
+ if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN)))
+ mcode_protfail(J);
return mc;
}
}