diff --git a/src/hlua.c b/src/hlua.c index 216d73a39..54d9fbcaf 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -9036,7 +9036,9 @@ struct task *hlua_process_task(struct task *task, void *context, unsigned int st SEND_ERR(NULL, "Lua task: execution timeout.\n"); goto err_task_abort; case HLUA_E_ERRMSG: + hlua_lock(hlua); SEND_ERR(NULL, "Lua task: %s.\n", hlua_tostring_safe(hlua->T, -1)); + hlua_unlock(hlua); goto err_task_abort; case HLUA_E_ERR: default: @@ -9311,7 +9313,9 @@ static void hlua_event_handler(struct hlua *hlua) break; case HLUA_E_ERRMSG: + hlua_lock(hlua); SEND_ERR(NULL, "Lua event_hdl: %s.\n", hlua_tostring_safe(hlua->T, -1)); + hlua_unlock(hlua); break; case HLUA_E_ERR: @@ -9999,9 +10003,12 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, switch (hlua_ctx_resume(stream->hlua, 0)) { /* finished. */ case HLUA_E_OK: + hlua_lock(stream->hlua); /* If the stack is empty, the function fails. */ - if (lua_gettop(stream->hlua->T) <= 0) + if (lua_gettop(stream->hlua->T) <= 0) { + hlua_unlock(stream->hlua); return 0; + } /* Convert the returned value in sample. */ hlua_lua2smp(stream->hlua->T, -1, smp); @@ -10010,6 +10017,7 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, */ smp_dup(smp); lua_pop(stream->hlua->T, 1); + hlua_unlock(stream->hlua); return 1; /* yield. */ @@ -10020,9 +10028,11 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(stream->hlua); SEND_ERR(stream->be, "Lua converter '%s': %s.\n", fcn->name, hlua_tostring_safe(stream->hlua->T, -1)); lua_pop(stream->hlua->T, 1); + hlua_unlock(stream->hlua); return 0; case HLUA_E_ETMOUT: @@ -10124,9 +10134,12 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp switch (hlua_ctx_resume(stream->hlua, 0)) { /* finished. */ case HLUA_E_OK: + hlua_lock(stream->hlua); /* If the stack is empty, the function fails. */ - if (lua_gettop(stream->hlua->T) <= 0) + if (lua_gettop(stream->hlua->T) <= 0) { + hlua_unlock(stream->hlua); return 0; + } /* Convert the returned value in sample. */ hlua_lua2smp(stream->hlua->T, -1, smp); @@ -10135,6 +10148,7 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp */ smp_dup(smp); lua_pop(stream->hlua->T, 1); + hlua_unlock(stream->hlua); /* Set the end of execution flag. */ smp->flags &= ~SMP_F_MAY_CHANGE; @@ -10148,9 +10162,11 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(stream->hlua); SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", fcn->name, hlua_tostring_safe(stream->hlua->T, -1)); lua_pop(stream->hlua->T, 1); + hlua_unlock(stream->hlua); return 0; case HLUA_E_ETMOUT: @@ -10460,8 +10476,10 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, /* finished. */ case HLUA_E_OK: /* Catch the return value */ + hlua_lock(s->hlua); if (lua_gettop(s->hlua->T) > 0) act_ret = lua_tointeger(s->hlua->T, -1); + hlua_unlock(s->hlua); /* Set timeout in the required channel. */ if (act_ret == ACT_RET_YIELD) { @@ -10501,9 +10519,11 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px, /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(s->hlua); SEND_ERR(px, "Lua function '%s': %s.\n", rule->arg.hlua_rule->fcn->name, hlua_tostring_safe(s->hlua->T, -1)); lua_pop(s->hlua->T, 1); + hlua_unlock(s->hlua); goto end; case HLUA_E_ETMOUT: @@ -10678,9 +10698,11 @@ void hlua_applet_tcp_fct(struct appctx *ctx) /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(hlua); SEND_ERR(px, "Lua applet tcp '%s': %s.\n", rule->arg.hlua_rule->fcn->name, hlua_tostring_safe(hlua->T, -1)); lua_pop(hlua->T, 1); + hlua_unlock(hlua); goto error; case HLUA_E_ETMOUT: @@ -10889,9 +10911,11 @@ void hlua_applet_http_fct(struct appctx *ctx) /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(hlua); SEND_ERR(px, "Lua applet http '%s': %s.\n", rule->arg.hlua_rule->fcn->name, hlua_tostring_safe(hlua->T, -1)); lua_pop(hlua->T, 1); + hlua_unlock(hlua); goto error; case HLUA_E_ETMOUT: @@ -11515,9 +11539,11 @@ static int hlua_cli_io_handler_fct(struct appctx *appctx) /* finished with error. */ case HLUA_E_ERRMSG: /* Display log. */ + hlua_lock(hlua); SEND_ERR(NULL, "Lua cli '%s': %s.\n", fcn->name, hlua_tostring_safe(hlua->T, -1)); lua_pop(hlua->T, 1); + hlua_unlock(hlua); return 1; case HLUA_E_ETMOUT: @@ -11928,9 +11954,25 @@ static int hlua_filter_new(struct stream *s, struct filter *filter) switch (hlua_ctx_resume(s->hlua, 0)) { case HLUA_E_OK: + /* The following Lua calls can fail. */ + if (!SET_SAFE_LJMP(s->hlua)) { + const char *error; + + hlua_lock(s->hlua); + if (lua_type(s->hlua->T, -1) == LUA_TSTRING) + error = hlua_tostring_safe(s->hlua->T, -1); + else + error = "critical error"; + SEND_ERR(s->be, "Lua filter '%s': %s.\n", conf->reg->name, error); + hlua_unlock(s->hlua); + ret = 0; + goto end; + } + /* Nothing returned or not a table, ignore the filter for current stream */ if (!lua_gettop(s->hlua->T) || !lua_istable(s->hlua->T, 1)) { ret = 0; + RESET_SAFE_LJMP(s->hlua); goto end; } @@ -11942,6 +11984,10 @@ static int hlua_filter_new(struct stream *s, struct filter *filter) /* Save a ref on the filter ctx */ lua_pushvalue(s->hlua->T, 1); flt_ctx->ref = hlua_ref(s->hlua->T); + + /* At this point the execution is safe. */ + RESET_SAFE_LJMP(s->hlua); + filter->ctx = flt_ctx; break; case HLUA_E_ERRMSG: @@ -12106,10 +12152,12 @@ static int hlua_filter_callback(struct stream *s, struct filter *filter, const c switch (hlua_ctx_resume(flt_hlua, !(flags & HLUA_FLT_CB_FINAL))) { case HLUA_E_OK: /* Catch the return value if it required */ + hlua_lock(flt_hlua); if ((flags & HLUA_FLT_CB_RETVAL) && lua_gettop(flt_hlua->T) > 0) { ret = lua_tointeger(flt_hlua->T, -1); lua_settop(flt_hlua->T, 0); /* Empty the stack. */ } + hlua_unlock(flt_hlua); /* Set timeout in the required channel. */ if (flt_hlua->wake_time != TICK_ETERNITY) { @@ -12138,7 +12186,9 @@ static int hlua_filter_callback(struct stream *s, struct filter *filter, const c ret = 0; goto end; case HLUA_E_ERRMSG: + hlua_lock(flt_hlua); SEND_ERR(s->be, "Lua filter '%s' : %s.\n", conf->reg->name, hlua_tostring_safe(flt_hlua->T, -1)); + hlua_unlock(flt_hlua); ret = -1; goto end; case HLUA_E_ETMOUT: