forked from LuaJIT/LuaJIT
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(cherry-picked from commit 9ebebc9) Before the patch, there was a situation where `luaL_newstate` could fail in main and the `argv[0]` could be used as a progname in `l_message`. However, `argv[0]` is not guaranteed to be non-NULL, so the segmentation fault could occur. This patch fixes the issue by using the predefined name in that case. Moreover, it refactors the `l_message`, so now there is no need to pass `pname` everywhere. The patch is tested with the help of the mocking of `luaL_newstate` by providing an error-injected implementation of it and preloading it. For preload to work, the LuaJIT must be built with dynamic build mode enabled. The corresponding flavor is added to the CI. The <gh-8594-sysprof-ffunc-crash.test.c> inspects internal symbols from the LuaJIT static library, so it can't be linked for shared build. The test is disabled for the dynamic build mode. Since the Linux kernel 5.18-rc1 release, `argv` is forced to a single empty string if it is empty [1], so the issue is not reproducible on new kernels. You may inspect the `dmesg` log for the corresponding warning entrance. Maxim Kokryashkin: * added the description and the test for the problem [1]: https://lore.kernel.org/all/[email protected]/ Part of tarantool/tarantool#10709
- Loading branch information
Showing
8 changed files
with
137 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
local tap = require('tap') | ||
local test = tap.test('fix-argv-handling'):skipcond({ | ||
['DYLD_INSERT_LIBRARIES does not work on macOS'] = jit.os == 'OSX', | ||
}) | ||
|
||
test:plan(1) | ||
|
||
-- XXX: Since the Linux kernel 5.18-rc1 release, `argv` is forced | ||
-- to a single empty string if it is empty [1], so the issue is | ||
-- not reproducible on new kernels. | ||
-- | ||
-- [1]: https://lore.kernel.org/all/[email protected]/ | ||
|
||
local utils = require('utils') | ||
local execlib = require('execlib') | ||
local cmd = utils.exec.luabin(arg) | ||
|
||
-- Start the LuaJIT with an empty argv array and mocked | ||
-- `luaL_newstate`. | ||
local output = execlib.empty_argv_exec(cmd) | ||
|
||
-- Without the patch, the test fails with a segmentation fault | ||
-- instead of returning an error. | ||
test:like(output, 'cannot create state', 'correct argv handling') | ||
test:done(true) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) | ||
BuildTestCLib(mynewstate mynewstate.c ${test_name}.test.lua) | ||
BuildTestCLib(execlib execlib.c ${test_name}.test.lua) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#define _GNU_SOURCE | ||
#include "lua.h" | ||
#include "lauxlib.h" | ||
|
||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/wait.h> | ||
#include <unistd.h> | ||
|
||
/* 1Kb should be enough. */ | ||
#define BUF_SIZE 1024 | ||
#define CHECKED(call) \ | ||
do { \ | ||
if ((call) == -1) { \ | ||
perror(#call); \ | ||
exit(1); \ | ||
} \ | ||
} while(0) | ||
|
||
static int empty_argv_exec(struct lua_State *L) | ||
{ | ||
const char *path = luaL_checkstring(L, -1); | ||
int pipefds[2] = {}; | ||
char *const argv[] = {NULL}; | ||
char buf[BUF_SIZE]; | ||
|
||
CHECKED(pipe2(pipefds, O_CLOEXEC)); | ||
|
||
pid_t pid = fork(); | ||
CHECKED(pid); | ||
|
||
if (pid == 0) { | ||
/* | ||
* Mock the `luaL_newstate` with an error-injected | ||
* version. | ||
*/ | ||
setenv("LD_PRELOAD", "mynewstate.so", 1); | ||
CHECKED(dup2(pipefds[1], STDOUT_FILENO)); | ||
CHECKED(dup2(pipefds[1], STDERR_FILENO)); | ||
/* | ||
* Pipes are closed on the exec call because of | ||
* the O_CLOEXEC flag. | ||
*/ | ||
CHECKED(execvp(path, argv)); | ||
} | ||
|
||
close(pipefds[1]); | ||
CHECKED(waitpid(pid, NULL, 0)); | ||
|
||
CHECKED(read(pipefds[0], buf, BUF_SIZE)); | ||
close(pipefds[0]); | ||
|
||
lua_pushstring(L, buf); | ||
return 1; | ||
} | ||
|
||
static const struct luaL_Reg execlib[] = { | ||
{"empty_argv_exec", empty_argv_exec}, | ||
{NULL, NULL} | ||
}; | ||
|
||
LUA_API int luaopen_execlib(lua_State *L) | ||
{ | ||
luaL_register(L, "execlib", execlib); | ||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include <stddef.h> | ||
|
||
struct lua_State; | ||
|
||
/* Error-injected mock. */ | ||
struct lua_State *luaL_newstate(void) | ||
{ | ||
return NULL; | ||
} |