BUG/MINOR: hlua: Fix memory leaks on error path when registering an action

When an error occurred in hlua_register_action(), the allocated lua function
and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.
This commit is contained in:
Christopher Faulet 2021-04-12 15:08:12 +02:00
parent 528526f2cc
commit 4fc9da01d2

View File

@ -7672,11 +7672,11 @@ static enum act_parse_ret action_register_service_http(const char **args, int *c
*/ */
__LJMP static int hlua_register_action(lua_State *L) __LJMP static int hlua_register_action(lua_State *L)
{ {
struct action_kw_list *akl; struct action_kw_list *akl = NULL;
const char *name; const char *name;
int ref; int ref;
int len; int len;
struct hlua_function *fcn; struct hlua_function *fcn = NULL;
int nargs; int nargs;
struct buffer *trash; struct buffer *trash;
struct action_kw *akw; struct action_kw *akw;
@ -7738,15 +7738,15 @@ __LJMP static int hlua_register_action(lua_State *L)
/* Allocate and fill the sample fetch keyword struct. */ /* Allocate and fill the sample fetch keyword struct. */
akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2); akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
if (!akl) if (!akl)
WILL_LJMP(luaL_error(L, "Lua out of memory error.")); goto alloc_error;;
fcn = new_hlua_function(); fcn = new_hlua_function();
if (!fcn) if (!fcn)
WILL_LJMP(luaL_error(L, "Lua out of memory error.")); goto alloc_error;
/* Fill fcn. */ /* Fill fcn. */
fcn->name = strdup(name); fcn->name = strdup(name);
if (!fcn->name) if (!fcn->name)
WILL_LJMP(luaL_error(L, "Lua out of memory error.")); goto alloc_error;
fcn->function_ref[hlua_state_id] = ref; fcn->function_ref[hlua_state_id] = ref;
/* Set the expected number of arguments. */ /* Set the expected number of arguments. */
@ -7759,7 +7759,7 @@ __LJMP static int hlua_register_action(lua_State *L)
len = strlen("lua.") + strlen(name) + 1; len = strlen("lua.") + strlen(name) + 1;
akl->kw[0].kw = calloc(1, len); akl->kw[0].kw = calloc(1, len);
if (!akl->kw[0].kw) if (!akl->kw[0].kw)
WILL_LJMP(luaL_error(L, "Lua out of memory error.")); goto alloc_error;
snprintf((char *)akl->kw[0].kw, len, "lua.%s", name); snprintf((char *)akl->kw[0].kw, len, "lua.%s", name);
@ -7776,15 +7776,30 @@ __LJMP static int hlua_register_action(lua_State *L)
http_req_keywords_register(akl); http_req_keywords_register(akl);
else if (strcmp(lua_tostring(L, -1), "http-res") == 0) else if (strcmp(lua_tostring(L, -1), "http-res") == 0)
http_res_keywords_register(akl); http_res_keywords_register(akl);
else else {
release_hlua_function(fcn);
if (akl)
ha_free((char **)&(akl->kw[0].kw));
ha_free(&akl);
WILL_LJMP(luaL_error(L, "Lua action environment '%s' is unknown. " WILL_LJMP(luaL_error(L, "Lua action environment '%s' is unknown. "
"'tcp-req', 'tcp-res', 'http-req' or 'http-res' " "'tcp-req', 'tcp-res', 'http-req' or 'http-res' "
"are expected.", lua_tostring(L, -1))); "are expected.", lua_tostring(L, -1)));
}
/* pop the environment string. */ /* pop the environment string. */
lua_pop(L, 1); lua_pop(L, 1);
/* reset for next loop */
akl = NULL;
fcn = NULL;
} }
return ACT_RET_PRS_OK; return ACT_RET_PRS_OK;
alloc_error:
release_hlua_function(fcn);
ha_free(&akl);
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
return 0; /* Never reached */
} }
static enum act_parse_ret action_register_service_tcp(const char **args, int *cur_arg, struct proxy *px, static enum act_parse_ret action_register_service_tcp(const char **args, int *cur_arg, struct proxy *px,