From: M9nx Date: Mon, 24 Aug 2026 04:15:42 +0000 (+0300) Subject: BUG/MINOR: hlua: release private Lua rule data on teardown X-Git-Tag: v3.5-dev8~137 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=3316314ee8613bc510733b2c151715c6bdbf5981;p=haproxy.git BUG/MINOR: hlua: release private Lua rule data on teardown Lua actions and services allocate a `struct hlua_rule` (and sometimes an arguments array) while parsing the configuration. The resulting private structure is stored in the generic `act_rule` structure. However, these parsers failed to register a `release_ptr` callback. As a result, when `free_act_rule()` destroys the parent rule during proxy teardown (e.g. at process exit or soft-reload deinit), it leaks the Lua-private allocation. This is exposed by LeakSanitizer when validating configurations that use Lua rules (e.g. `examples/games.cfg -c`). This is a configuration/process-lifetime data leak rather than a per-request or per-connection leak. It does not accumulate during normal runtime operation. This patch fixes the issue by adding a common release callback and assigning it in all three Lua parsers that allocate this structure (`action_register_lua`, `action_register_service_http`, and `action_register_service_tcp`). The callback frees the `hlua_rule` and any owned argument strings, while deliberately leaving the borrowed `hlua_function` untouched. This fixes issue #3480. Backport status: may be backported to all supported versions. --- diff --git a/src/hlua.c b/src/hlua.c index d24f05977..58b6bbe8e 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -11142,6 +11142,21 @@ static void hlua_applet_http_release(struct appctx *ctx) http_ctx->hlua = NULL; } +/* Release the private data attached to a Lua action or service rule. */ +static void release_hlua_rule(struct act_rule *rule) +{ + if (rule->arg.hlua_rule) { + if (rule->arg.hlua_rule->args) { + int i; + + for (i = 0; rule->arg.hlua_rule->args[i]; i++) + ha_free(&rule->arg.hlua_rule->args[i]); + ha_free(&rule->arg.hlua_rule->args); + } + ha_free(&rule->arg.hlua_rule); + } +} + /* global {tcp|http}-request parser. Return ACT_RET_PRS_OK in * success case, else return ACT_RET_PRS_ERR. * @@ -11190,6 +11205,7 @@ static enum act_parse_ret action_register_lua(const char **args, int *cur_arg, s rule->action = ACT_CUSTOM; rule->action_ptr = hlua_action; + rule->release_ptr = release_hlua_rule; return ACT_RET_PRS_OK; error: @@ -11243,6 +11259,7 @@ static enum act_parse_ret action_register_service_http(const char **args, int *c rule->applet.fct = hlua_applet_http_fct; rule->applet.release = hlua_applet_http_release; rule->applet.timeout = hlua_timeout_applet; + rule->release_ptr = release_hlua_rule; return ACT_RET_PRS_OK; } @@ -11431,6 +11448,7 @@ static enum act_parse_ret action_register_service_tcp(const char **args, int *cu rule->applet.fct = hlua_applet_tcp_fct; rule->applet.release = hlua_applet_tcp_release; rule->applet.timeout = hlua_timeout_applet; + rule->release_ptr = release_hlua_rule; return 0; }