mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-27 13:51:00 +01:00
BUG/MEDIUM: lua: Always init the lua stack before referencing the context
When a lua context is allocated, its stack must be initialized to NULL before attaching it to its owner (task, stream or applet). Otherwise, if the watchdog is fired before the stack is really created, that may lead to a segfault because we try to dump the traceback of an uninitialized lua stack. It is easy to trigger this bug if a lua script do a blocking call while another thread try to initialize a new lua context. Because of the global lua lock, the init is blocked before the stack creation. Of course, it only happens if the script is executed in the shared global context. This patch must be backported as far as 2.0.
This commit is contained in:
parent
cc2c4f8f4c
commit
1e8433f594
25
src/hlua.c
25
src/hlua.c
@ -6403,6 +6403,7 @@ static int hlua_register_task(lua_State *L)
|
|||||||
hlua = pool_alloc(pool_head_hlua);
|
hlua = pool_alloc(pool_head_hlua);
|
||||||
if (!hlua)
|
if (!hlua)
|
||||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||||
|
HLUA_INIT(hlua);
|
||||||
|
|
||||||
/* We are in the common lua state, execute the task anywhere,
|
/* We are in the common lua state, execute the task anywhere,
|
||||||
* otherwise, inherit the current thread identifier
|
* otherwise, inherit the current thread identifier
|
||||||
@ -6449,11 +6450,15 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp,
|
|||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!stream->hlua) {
|
if (!stream->hlua) {
|
||||||
stream->hlua = pool_alloc(pool_head_hlua);
|
struct hlua *hlua;
|
||||||
if (!stream->hlua) {
|
|
||||||
|
hlua = pool_alloc(pool_head_hlua);
|
||||||
|
if (!hlua) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
HLUA_INIT(hlua);
|
||||||
|
stream->hlua = hlua;
|
||||||
if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
|
if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
return 0;
|
return 0;
|
||||||
@ -6582,11 +6587,15 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
|
|||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!stream->hlua) {
|
if (!stream->hlua) {
|
||||||
stream->hlua = pool_alloc(pool_head_hlua);
|
struct hlua *hlua;
|
||||||
if (!stream->hlua) {
|
|
||||||
|
hlua = pool_alloc(pool_head_hlua);
|
||||||
|
if (!hlua) {
|
||||||
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
hlua->T = NULL;
|
||||||
|
stream->hlua = hlua;
|
||||||
if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
|
if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
|
||||||
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
return 0;
|
return 0;
|
||||||
@ -6893,12 +6902,16 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
|
|||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!s->hlua) {
|
if (!s->hlua) {
|
||||||
s->hlua = pool_alloc(pool_head_hlua);
|
struct hlua *hlua;
|
||||||
if (!s->hlua) {
|
|
||||||
|
hlua = pool_alloc(pool_head_hlua);
|
||||||
|
if (!hlua) {
|
||||||
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
||||||
rule->arg.hlua_rule->fcn->name);
|
rule->arg.hlua_rule->fcn->name);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
HLUA_INIT(hlua);
|
||||||
|
s->hlua = hlua;
|
||||||
if (!hlua_ctx_init(s->hlua, fcn_ref_to_stack_id(rule->arg.hlua_rule->fcn), s->task, 0)) {
|
if (!hlua_ctx_init(s->hlua, fcn_ref_to_stack_id(rule->arg.hlua_rule->fcn), s->task, 0)) {
|
||||||
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
||||||
rule->arg.hlua_rule->fcn->name);
|
rule->arg.hlua_rule->fcn->name);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user