diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.dep | 4 | ||||
| -rw-r--r-- | src/lj_errmsg.h | 1 | ||||
| -rw-r--r-- | src/lj_mcode.c | 35 |
3 files changed, 27 insertions, 13 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep index 5b35ddf5..97f8125a 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -138,8 +138,8 @@ lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ | |||
| 138 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \ | 138 | lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \ |
| 139 | lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h | 139 | lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h |
| 140 | lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 140 | lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 141 | lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \ | 141 | lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \ |
| 142 | lj_traceerr.h lj_vm.h | 142 | lj_dispatch.h lj_bc.h lj_traceerr.h lj_vm.h |
| 143 | lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 143 | lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 144 | lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \ | 144 | lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \ |
| 145 | lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h | 145 | lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h |
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index e62dc237..8f01fdc7 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h | |||
| @@ -100,6 +100,7 @@ ERRDEF(STRFMT, "invalid option " LUA_QS " to " LUA_QL("format")) | |||
| 100 | ERRDEF(STRGSRV, "invalid replacement value (a %s)") | 100 | ERRDEF(STRGSRV, "invalid replacement value (a %s)") |
| 101 | ERRDEF(BADMODN, "name conflict for module " LUA_QS) | 101 | ERRDEF(BADMODN, "name conflict for module " LUA_QS) |
| 102 | #if LJ_HASJIT | 102 | #if LJ_HASJIT |
| 103 | ERRDEF(JITPROT, "runtime code generation failed, restricted kernel?") | ||
| 103 | #if LJ_TARGET_X86ORX64 | 104 | #if LJ_TARGET_X86ORX64 |
| 104 | ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2") | 105 | ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2") |
| 105 | #else | 106 | #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 @@ | |||
| 9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
| 10 | #if LJ_HASJIT | 10 | #if LJ_HASJIT |
| 11 | #include "lj_gc.h" | 11 | #include "lj_gc.h" |
| 12 | #include "lj_err.h" | ||
| 12 | #include "lj_jit.h" | 13 | #include "lj_jit.h" |
| 13 | #include "lj_mcode.h" | 14 | #include "lj_mcode.h" |
| 14 | #include "lj_trace.h" | 15 | #include "lj_trace.h" |
| @@ -78,10 +79,10 @@ static void mcode_free(jit_State *J, void *p, size_t sz) | |||
| 78 | VirtualFree(p, 0, MEM_RELEASE); | 79 | VirtualFree(p, 0, MEM_RELEASE); |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | static void mcode_setprot(void *p, size_t sz, DWORD prot) | 82 | static int mcode_setprot(void *p, size_t sz, DWORD prot) |
| 82 | { | 83 | { |
| 83 | DWORD oprot; | 84 | DWORD oprot; |
| 84 | VirtualProtect(p, sz, prot, &oprot); | 85 | return !VirtualProtect(p, sz, prot, &oprot); |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | #elif LJ_TARGET_POSIX | 88 | #elif LJ_TARGET_POSIX |
| @@ -112,9 +113,9 @@ static void mcode_free(jit_State *J, void *p, size_t sz) | |||
| 112 | munmap(p, sz); | 113 | munmap(p, sz); |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | static void mcode_setprot(void *p, size_t sz, int prot) | 116 | static int mcode_setprot(void *p, size_t sz, int prot) |
| 116 | { | 117 | { |
| 117 | mprotect(p, sz, prot); | 118 | return mprotect(p, sz, prot); |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | #elif LJ_64 | 121 | #elif LJ_64 |
| @@ -140,8 +141,6 @@ static void mcode_free(jit_State *J, void *p, size_t sz) | |||
| 140 | lj_mem_free(J2G(J), p, sz); | 141 | lj_mem_free(J2G(J), p, sz); |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | #define mcode_setprot(p, sz, prot) UNUSED(p) | ||
| 144 | |||
| 145 | #endif | 144 | #endif |
| 146 | 145 | ||
| 147 | /* -- MCode area protection ----------------------------------------------- */ | 146 | /* -- MCode area protection ----------------------------------------------- */ |
| @@ -180,11 +179,23 @@ static void mcode_protect(jit_State *J, int prot) | |||
| 180 | #define MCPROT_GEN MCPROT_RW | 179 | #define MCPROT_GEN MCPROT_RW |
| 181 | #define MCPROT_RUN MCPROT_RX | 180 | #define MCPROT_RUN MCPROT_RX |
| 182 | 181 | ||
| 182 | /* Protection twiddling failed. Probably due to kernel security. */ | ||
| 183 | static LJ_NOINLINE void mcode_protfail(jit_State *J) | ||
| 184 | { | ||
| 185 | lua_CFunction panic = J2G(J)->panic; | ||
| 186 | if (panic) { | ||
| 187 | lua_State *L = J->L; | ||
| 188 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITPROT)); | ||
| 189 | panic(L); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 183 | /* Change protection of MCode area. */ | 193 | /* Change protection of MCode area. */ |
| 184 | static void mcode_protect(jit_State *J, int prot) | 194 | static void mcode_protect(jit_State *J, int prot) |
| 185 | { | 195 | { |
| 186 | if (J->mcprot != prot) { | 196 | if (J->mcprot != prot) { |
| 187 | mcode_setprot(J->mcarea, J->szmcarea, prot); | 197 | if (LJ_UNLIKELY(mcode_setprot(J->mcarea, J->szmcarea, prot))) |
| 198 | mcode_protfail(J); | ||
| 188 | J->mcprot = prot; | 199 | J->mcprot = prot; |
| 189 | } | 200 | } |
| 190 | } | 201 | } |
| @@ -305,7 +316,8 @@ void lj_mcode_commit(jit_State *J, MCode *top) | |||
| 305 | /* Abort the reservation. */ | 316 | /* Abort the reservation. */ |
| 306 | void lj_mcode_abort(jit_State *J) | 317 | void lj_mcode_abort(jit_State *J) |
| 307 | { | 318 | { |
| 308 | mcode_protect(J, MCPROT_RUN); | 319 | if (J->mcarea) |
| 320 | mcode_protect(J, MCPROT_RUN); | ||
| 309 | } | 321 | } |
| 310 | 322 | ||
| 311 | /* Set/reset protection to allow patching of MCode areas. */ | 323 | /* Set/reset protection to allow patching of MCode areas. */ |
| @@ -318,8 +330,8 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) | |||
| 318 | if (finish) { | 330 | if (finish) { |
| 319 | if (J->mcarea == ptr) | 331 | if (J->mcarea == ptr) |
| 320 | mcode_protect(J, MCPROT_RUN); | 332 | mcode_protect(J, MCPROT_RUN); |
| 321 | else | 333 | else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) |
| 322 | mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN); | 334 | mcode_protfail(J); |
| 323 | return NULL; | 335 | return NULL; |
| 324 | } else { | 336 | } else { |
| 325 | MCode *mc = J->mcarea; | 337 | MCode *mc = J->mcarea; |
| @@ -333,7 +345,8 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) | |||
| 333 | mc = ((MCLink *)mc)->next; | 345 | mc = ((MCLink *)mc)->next; |
| 334 | lua_assert(mc != NULL); | 346 | lua_assert(mc != NULL); |
| 335 | if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) { | 347 | if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) { |
| 336 | mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN); | 348 | if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN))) |
| 349 | mcode_protfail(J); | ||
| 337 | return mc; | 350 | return mc; |
| 338 | } | 351 | } |
| 339 | } | 352 | } |
