]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: hlua: unlock Patref before add_bulk type error
authorKelly Kane <kelly@hawknetworks.com>
Sun, 25 Oct 2026 01:03:03 +0000 (01:03 +0000)
committerAurelien DARRAGON <adarragon@haproxy.com>
Tue, 27 Oct 2026 11:58:43 +0000 (12:58 +0100)
Patref:add_bulk checks table entries while holding the pattern reference
write lock. luaL_checktype() raises on a non-string entry and bypasses
the unlock, blocking later updates. Check types without raising while
locked, then unlock before reporting the original Lua error.

Signed-off-by: Kelly Kane <kelly@hawknetworks.com>
It should be backported to 3.2.

src/hlua_fcn.c

index 5a53e52123c899c9b577853a9ea242aaa12d12b8..15e96346ba6e2acdea4ff6badb7063c205115939 100644 (file)
@@ -2928,14 +2928,26 @@ static int _hlua_patref_add_bulk(lua_State *L, int status, lua_KContext ctx)
 
                if (ref->ptr->flags & PAT_REF_SMP) {
                        /* key:val table */
-                       luaL_checktype(L, -2, LUA_TSTRING);
+                       if (lua_type(L, -2) != LUA_TSTRING) {
+                               HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
+                               luaL_checktype(L, -2, LUA_TSTRING);
+                               return 0; // not reached
+                       }
                        key = lua_tostring(L, -2);
-                       luaL_checktype(L, -1, LUA_TSTRING);
+                       if (lua_type(L, -1) != LUA_TSTRING) {
+                               HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
+                               luaL_checktype(L, -1, LUA_TSTRING);
+                               return 0; // not reached
+                       }
                        value = lua_tostring(L, -1);
                }
                else {
                        /* key-only table, use value as key */
-                       luaL_checktype(L, -1, LUA_TSTRING);
+                       if (lua_type(L, -1) != LUA_TSTRING) {
+                               HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
+                               luaL_checktype(L, -1, LUA_TSTRING);
+                               return 0; // not reached
+                       }
                        key = lua_tostring(L, -1);
                }