]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: hlua: fix unsafe lua_tostring() usage with empty stack
authorAurelien DARRAGON <adarragon@haproxy.com>
Fri, 1 Mar 2024 18:54:16 +0000 (19:54 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Mon, 4 Mar 2024 15:46:53 +0000 (16:46 +0100)
Lua documentation says that lua_tostring() returns a pointer that remains
valid as long as the object is not removed from the stack.

However there are some places were we use the returned string AFTER the
corresponding object is removed from the stack. In practise this doesn't
seem to cause visible bugs (probably because the pointer remains valid
waiting for a GC cycle), but let's fix that to comply with the
documentation and avoid undefined behavior.

It should be backported in all stable versions.

src/hlua.c

index d915b1087427dba9dbb5d17bfbb3c375a6aaf975..d8dcbf260a4469c0f8e4e5e8178e8f5ababc5703 100644 (file)
@@ -1821,12 +1821,15 @@ resume_execution:
                        break;
                }
                msg = lua_tostring(lua->T, -1);
-               lua_settop(lua->T, 0); /* Empty the stack. */
                trace = hlua_traceback(lua->T, ", ");
                if (msg)
                        lua_pushfstring(lua->T, "[state-id %d] runtime error: %s from %s", lua->state_id, msg, trace);
                else
                        lua_pushfstring(lua->T, "[state-id %d] unknown runtime error from %s", lua->state_id, trace);
+
+               /* Move the error msg at the top and then empty the stack except last msg */
+               lua_insert(lua->T, -lua_gettop(lua->T));
+               lua_settop(lua->T, 1);
                ret = HLUA_E_ERRMSG;
                break;
 
@@ -1843,11 +1846,14 @@ resume_execution:
                        break;
                }
                msg = lua_tostring(lua->T, -1);
-               lua_settop(lua->T, 0); /* Empty the stack. */
                if (msg)
                        lua_pushfstring(lua->T, "[state-id %d] message handler error: %s", lua->state_id, msg);
                else
                        lua_pushfstring(lua->T, "[state-id %d] message handler error", lua->state_id);
+
+               /* Move the error msg at the top and then empty the stack except last msg */
+               lua_insert(lua->T, -lua_gettop(lua->T));
+               lua_settop(lua->T, 1);
                ret = HLUA_E_ERRMSG;
                break;
 
@@ -13039,12 +13045,13 @@ int hlua_post_init_state(lua_State *L)
                        if (!kind)
                                kind = "runtime error";
                        msg = lua_tostring(L, -1);
-                       lua_settop(L, 0); /* Empty the stack. */
                        trace = hlua_traceback(L, ", ");
                        if (msg)
                                ha_alert("Lua init: %s: '%s' from %s\n", kind, msg, trace);
                        else
                                ha_alert("Lua init: unknown %s from %s\n", kind, trace);
+
+                       lua_settop(L, 0); /* Empty the stack. */
                        return_status = 0;
                        break;