diff options
author | Mike Pall <mike> | 2013-10-24 15:19:03 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2013-10-24 15:19:03 +0200 |
commit | 7e538b5f0ae1dfa7667f3a974d570f0cd8190aca (patch) | |
tree | b49722230d9e608d2071bba20bbc2e9bbd919f3b /src/lj_mcode.c | |
parent | 4fba08a9aca4ce99a6a51f5faca2e1e091ad1422 (diff) | |
download | luajit-7e538b5f0ae1dfa7667f3a974d570f0cd8190aca.tar.gz luajit-7e538b5f0ae1dfa7667f3a974d570f0cd8190aca.tar.bz2 luajit-7e538b5f0ae1dfa7667f3a974d570f0cd8190aca.zip |
Check for failure to mark memory as executable (restricted kernels).
Diffstat (limited to 'src/lj_mcode.c')
-rw-r--r-- | src/lj_mcode.c | 35 |
1 files changed, 24 insertions, 11 deletions
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 | } |