From 1c07da4b48f680f0de871b2a87a21c1dd05a1ed9 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Wed, 17 May 2023 16:06:11 +0200 Subject: [PATCH] BUG/MINOR: hlua: unsafe hlua_lua2smp() usage Fixing hlua_lua2smp() usage in hlua's code since it was assumed that hlua_lua2smp() makes a standalone smp out of lua data, but it is not the case. This is especially true when dealing with lua strings (string is extracted using lua_tolstring() which returns a pointer to lua string memory location that may be reclaimed by lua at any time when no longer used from lua's point of view). Thus, smp generated by hlua_lua2smp() may only be used from the lua context where the call was initially made, else it should be explicitly duplicated before exporting it out of lua's context to ensure safe (standalone) usage. This should be backported to all stable versions. --- src/hlua.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/hlua.c b/src/hlua.c index ad045e1f1d..742c82448b 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -4689,7 +4689,9 @@ __LJMP static int hlua_applet_tcp_set_var(lua_State *L) memset(&smp, 0, sizeof(smp)); hlua_lua2smp(L, 3, &smp); - /* Store the sample in a variable. */ + /* Store the sample in a variable. We don't need to dup the smp, vars API + * already takes care of duplicating dynamic var data. + */ smp_set_owner(&smp, s->be, s->sess, s, 0); if (lua_gettop(L) == 4 && lua_toboolean(L, 4)) @@ -5178,7 +5180,9 @@ __LJMP static int hlua_applet_http_set_var(lua_State *L) memset(&smp, 0, sizeof(smp)); hlua_lua2smp(L, 3, &smp); - /* Store the sample in a variable. */ + /* Store the sample in a variable. We don't need to dup the smp, vars API + * already takes care of duplicating dynamic var data. + */ smp_set_owner(&smp, s->be, s->sess, s, 0); if (lua_gettop(L) == 4 && lua_toboolean(L, 4)) @@ -7783,7 +7787,9 @@ __LJMP static int hlua_set_var(lua_State *L) memset(&smp, 0, sizeof(smp)); hlua_lua2smp(L, 3, &smp); - /* Store the sample in a variable. */ + /* Store the sample in a variable. We don't need to dup the smp, vars API + * already takes care of duplicating dynamic var data. + */ smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR); if (lua_gettop(L) == 4 && lua_toboolean(L, 4)) @@ -9777,6 +9783,10 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, /* Convert the returned value in sample. */ hlua_lua2smp(stream->hlua->T, -1, smp); + /* dup the smp before popping the related lua value and + * returning it to haproxy + */ + smp_dup(smp); lua_pop(stream->hlua->T, 1); return 1; @@ -9912,6 +9922,10 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp /* Convert the returned value in sample. */ hlua_lua2smp(stream->hlua->T, -1, smp); + /* dup the smp before popping the related lua value and + * returning it to haproxy + */ + smp_dup(smp); lua_pop(stream->hlua->T, 1); /* Set the end of execution flag. */