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.
---
src/hlua.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/hlua.c b/src/hlua.c
index 1882db98a..bcfef7d57 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -11131,6 +11131,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.
*
@@ -11179,6 +11194,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:
@@ -11232,6 +11248,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;
}
@@ -11420,6 +11437,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;
}
--
2.55.0