Skip to content

Commit

Permalink
Always exit after machine code page protection change fails.
Browse files Browse the repository at this point in the history
Reported by Sergey Kaplun.

(cherry picked from commit c50232e)
  • Loading branch information
Mike Pall authored and igormunkin committed Aug 16, 2023
1 parent f0d6df4 commit cfe4f1f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/lj_mcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,15 @@ static void mcode_protect(jit_State *J, int prot)
#define MCPROT_RUN MCPROT_RX

/* Protection twiddling failed. Probably due to kernel security. */
static LJ_NOINLINE void mcode_protfail(jit_State *J)
static LJ_NORET 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);
}
exit(EXIT_FAILURE);
}

/* Change protection of MCode area. */
Expand Down
1 change: 1 addition & 0 deletions test/tarantool-tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ add_subdirectory(gh-6189-cur_L)
add_subdirectory(lj-416-xor-before-jcc)
add_subdirectory(lj-601-fix-gc-finderrfunc)
add_subdirectory(lj-727-lightuserdata-itern)
add_subdirectory(lj-802-panic-at-mcode-protfail)
add_subdirectory(lj-flush-on-trace)

# The part of the memory profiler toolchain is located in tools
Expand Down
26 changes: 26 additions & 0 deletions test/tarantool-tests/lj-802-panic-at-mcode-protfail.test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
local tap = require('tap')
local test = tap.test('lj-flush-on-trace'):skipcond({
['Test requires JIT enabled'] = not jit.status(),
['Disabled on *BSD due to #4819'] = jit.os == 'BSD',
['mprotect overriding can break Tarantool'] = _TARANTOOL,
})

test:plan(3)

-- <makecmd> runs %testname%/script.lua by <LUAJIT_TEST_BINARY>
-- with the given environment, launch options and CLI arguments.
local script = require('utils').exec.makecmd(arg, {
env = { LD_PRELOAD = 'mymprotect.so' },
redirect = '2>&1',
})

local poison = 'runtime code generation succeed'
local output = script(poison)
test:like(output, 'runtime code generation failed, restricted kernel%?',
'Panic occurred as a result of <mprotect> failure')
test:unlike(output, 'Segmentation fault',
'LuaJIT exited as a result of the panic (error check)')
test:unlike(output, poison,
'LuaJIT exited as a result of the panic (poison check)')

test:done(true)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BuildTestCLib(mymprotect mymprotect.c)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <sys/mman.h>

int mprotect(void *addr, size_t len, int prot)
{
return -1;
}
11 changes: 11 additions & 0 deletions test/tarantool-tests/lj-802-panic-at-mcode-protfail/script.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
jit.opt.start('hotloop=1')

-- XXX:
local a = 0
for i = 1, 3 do
a = a + i
end

-- XXX: Just a simple contract in case if panic at <mprotect>
-- failure didn't occur.
io.write(arg[1])

0 comments on commit cfe4f1f

Please sign in to comment.