mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-08 04:21:09 +01:00
BUG/MINOR: hlua: prevent function and table reference leaks on errors
Several error paths were leaking function or table references. (Obtained through hlua_checkfunction() and hlua_checktable() functions) Now we properly release the references thanks to hlua_unref() in such cases. This commit depends on "MINOR: hlua: add simple hlua reference handling API" This could be backported in every stable versions although it is not mandatory as such leaks only occur on rare error/warn paths. [prior to 2.5 lua filter API did not exist, the hlua_register_filter() part should be skipped]
This commit is contained in:
parent
16d047b615
commit
55afbedfb4
35
src/hlua.c
35
src/hlua.c
@ -8657,8 +8657,10 @@ __LJMP static int hlua_register_init(lua_State *L)
|
||||
ref = MAY_LJMP(hlua_checkfunction(L, 1));
|
||||
|
||||
init = calloc(1, sizeof(*init));
|
||||
if (!init)
|
||||
if (!init) {
|
||||
hlua_unref(L, ref);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
}
|
||||
|
||||
init->function_ref = ref;
|
||||
LIST_APPEND(&hlua_init_functions[hlua_state_id], &init->l);
|
||||
@ -8731,6 +8733,7 @@ static int hlua_register_task(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
task_destroy(task);
|
||||
hlua_unref(L, ref);
|
||||
hlua_ctx_destroy(hlua);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
@ -9044,6 +9047,7 @@ __LJMP static int hlua_register_converters(lua_State *L)
|
||||
if (fcn->function_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register converter 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", name);
|
||||
hlua_unref(L, fcn->function_ref[hlua_state_id]);
|
||||
}
|
||||
fcn->function_ref[hlua_state_id] = ref;
|
||||
return 0;
|
||||
@ -9087,6 +9091,7 @@ __LJMP static int hlua_register_converters(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
ha_free(&sck);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
@ -9128,6 +9133,7 @@ __LJMP static int hlua_register_fetches(lua_State *L)
|
||||
if (fcn->function_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register sample-fetch 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", name);
|
||||
hlua_unref(L, fcn->function_ref[hlua_state_id]);
|
||||
}
|
||||
fcn->function_ref[hlua_state_id] = ref;
|
||||
return 0;
|
||||
@ -9172,6 +9178,7 @@ __LJMP static int hlua_register_fetches(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
ha_free(&sfk);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
@ -9976,8 +9983,10 @@ __LJMP static int hlua_register_action(lua_State *L)
|
||||
/* browse the second argument as an array. */
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0) {
|
||||
if (lua_type(L, -1) != LUA_TSTRING)
|
||||
if (lua_type(L, -1) != LUA_TSTRING) {
|
||||
hlua_unref(L, ref);
|
||||
WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
|
||||
}
|
||||
|
||||
/* Check if action exists */
|
||||
trash = get_trash_chunk();
|
||||
@ -9998,6 +10007,7 @@ __LJMP static int hlua_register_action(lua_State *L)
|
||||
if (fcn->function_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register action 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", name);
|
||||
hlua_unref(L, fcn->function_ref[hlua_state_id]);
|
||||
}
|
||||
fcn->function_ref[hlua_state_id] = ref;
|
||||
|
||||
@ -10050,6 +10060,7 @@ __LJMP static int hlua_register_action(lua_State *L)
|
||||
http_res_keywords_register(akl);
|
||||
else {
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
if (akl)
|
||||
ha_free((char **)&(akl->kw[0].kw));
|
||||
ha_free(&akl);
|
||||
@ -10069,6 +10080,7 @@ __LJMP static int hlua_register_action(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
ha_free(&akl);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
@ -10148,6 +10160,7 @@ __LJMP static int hlua_register_service(lua_State *L)
|
||||
if (fcn->function_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register service 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", name);
|
||||
hlua_unref(L, fcn->function_ref[hlua_state_id]);
|
||||
}
|
||||
fcn->function_ref[hlua_state_id] = ref;
|
||||
return 0;
|
||||
@ -10187,6 +10200,7 @@ __LJMP static int hlua_register_service(lua_State *L)
|
||||
akl->kw[0].parse = action_register_service_http;
|
||||
else {
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
if (akl)
|
||||
ha_free((char **)&(akl->kw[0].kw));
|
||||
ha_free(&akl);
|
||||
@ -10207,6 +10221,7 @@ __LJMP static int hlua_register_service(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref);
|
||||
ha_free(&akl);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
@ -10428,10 +10443,14 @@ __LJMP static int hlua_register_cli(lua_State *L)
|
||||
lua_pushnil(L);
|
||||
memset(kw, 0, sizeof(kw));
|
||||
while (lua_next(L, 1) != 0) {
|
||||
if (index >= CLI_PREFIX_KW_NB)
|
||||
if (index >= CLI_PREFIX_KW_NB) {
|
||||
hlua_unref(L, ref_io);
|
||||
WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
|
||||
if (lua_type(L, -1) != LUA_TSTRING)
|
||||
}
|
||||
if (lua_type(L, -1) != LUA_TSTRING) {
|
||||
hlua_unref(L, ref_io);
|
||||
WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
|
||||
}
|
||||
kw[index] = lua_tostring(L, -1);
|
||||
if (index == 0)
|
||||
chunk_printf(trash, "%s", kw[index]);
|
||||
@ -10446,6 +10465,7 @@ __LJMP static int hlua_register_cli(lua_State *L)
|
||||
if (fcn->function_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register CLI keyword 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", trash->area);
|
||||
hlua_unref(L, fcn->function_ref[hlua_state_id]);
|
||||
}
|
||||
fcn->function_ref[hlua_state_id] = ref_io;
|
||||
return 0;
|
||||
@ -10521,6 +10541,7 @@ __LJMP static int hlua_register_cli(lua_State *L)
|
||||
|
||||
error:
|
||||
release_hlua_function(fcn);
|
||||
hlua_unref(L, ref_io);
|
||||
if (cli_kws) {
|
||||
for (i = 0; i < index; i++)
|
||||
ha_free((char **)&(cli_kws->kw[0].str_kw[i]));
|
||||
@ -11251,6 +11272,10 @@ __LJMP static int hlua_register_filter(lua_State *L)
|
||||
if (reg_flt->flt_ref[hlua_state_id] != -1 || reg_flt->fun_ref[hlua_state_id] != -1) {
|
||||
ha_warning("Trying to register filter 'lua.%s' more than once. "
|
||||
"This will become a hard error in version 2.5.\n", name);
|
||||
if (reg_flt->flt_ref[hlua_state_id] != -1)
|
||||
hlua_unref(L, reg_flt->flt_ref[hlua_state_id]);
|
||||
if (reg_flt->fun_ref[hlua_state_id] != -1)
|
||||
hlua_unref(L, reg_flt->fun_ref[hlua_state_id]);
|
||||
}
|
||||
reg_flt->flt_ref[hlua_state_id] = flt_ref;
|
||||
reg_flt->fun_ref[hlua_state_id] = fun_ref;
|
||||
@ -11288,6 +11313,8 @@ __LJMP static int hlua_register_filter(lua_State *L)
|
||||
|
||||
alloc_error:
|
||||
release_hlua_reg_filter(reg_flt);
|
||||
hlua_unref(L, flt_ref);
|
||||
hlua_unref(L, fun_ref);
|
||||
ha_free(&fkl);
|
||||
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
|
||||
return 0; /* Never reached */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user