From ffd262eed88eae9a7723529ae3cd073cd9ac4063 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Fri, 7 Aug 2026 17:07:36 +0200 Subject: [PATCH] BUG/MEDIUM: hlua_fcn: ensure systematic bref cleanup for patref list iterator Similar bug as aeff2a3b2a ("BUG/MEDIUM: hlua_fcn: ensure systematic watcher cleanup for server list iterator") but this time it affects patref list iterator. If the patref list iteration is interrupted (ie: break away from the loop or lua error), we still need to unlink the bref we set earlier because the hlua_patref_iterator_context is a temporary object so we cannot let a reference once the object is dead. Obviously this can corrupt the pattern reference element bref "users" list and lead to invalid reads as well. Reported-by: Claude (ANT-2026-DARC9AY8) It should be backported up to 3.2 where hlua patref API was implemented. --- src/hlua_fcn.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index 6424fe2bb..44f37b199 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -3203,6 +3203,25 @@ int hlua_listable_patref_pairs_iterator(lua_State *L) return _hlua_listable_patref_pairs_iterator(L, LUA_OK, 0); } +/* ensure proper cleanup for listable_patref_pairs */ +int hlua_listable_patref_pairs_gc(lua_State *L) +{ + struct hlua_patref_iterator_context *ctx; + + ctx = lua_touserdata(L, 1); + + /* we need to make sure that bref is unlinked even if the + * iterator was interrupted (ie: "break" from the loop), else the + * patref iterator element may still be accessed while it is no + * longer in memory scope (this can lead to invalid reads as well + * as pat_ref_elt list corruption). + */ + HA_RWLOCK_WRLOCK(PATREF_LOCK, &ctx->ref->ptr->lock); + LIST_DEL_INIT(&ctx->bref.users); + HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ctx->ref->ptr->lock); + return 0; +} + /* init the iterator context, return iterator function * with context as closure. The only argument is a * patref list object. @@ -3215,6 +3234,12 @@ int hlua_listable_patref_pairs(lua_State *L) ref = hlua_checkudata(L, 1, class_patref_ref); ctx = lua_newuserdata(L, sizeof(*ctx)); + + /* add gc metamethod to the newly created userdata */ + lua_newtable(L); + hlua_class_function(L, "__gc", hlua_listable_patref_pairs_gc); + lua_setmetatable(L, -2); + ctx->ref = ref; LIST_INIT(&ctx->bref.users); -- 2.47.3