From b8de1b2542dedf8ab92a51e74b6f2a27c8d70e7b Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 19 Dec 2025 09:39:59 +0000 Subject: [PATCH] [Fix] Release Redis connection in lua_redis_fin to avoid double-free Also set ud->ctx = NULL so lua_redis_dtor won't try to release again during Lua GC after the pool may have been destroyed. --- src/lua/lua_redis.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 4f70025472..769519c2e5 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -261,6 +261,7 @@ lua_redis_fin(void *arg) struct lua_redis_request_specific_userdata *sp_ud = arg; struct lua_redis_userdata *ud; struct lua_redis_ctx *ctx; + redisAsyncContext *ac; ctx = sp_ud->ctx; ud = sp_ud->common_ud; @@ -272,8 +273,18 @@ lua_redis_fin(void *arg) msg_debug_lua_redis("finished redis query %p from session %p; refcount=%d", sp_ud, ctx, ctx->ref.refcount); sp_ud->flags |= LUA_REDIS_SPECIFIC_FINISHED; - /* Prevent callbacks from accessing task data after session cleanup */ - ud->terminated = 1; + + if (!ud->terminated) { + /* Release Redis connection to prevent callbacks after session cleanup */ + ud->terminated = 1; + ac = ud->ctx; + ud->ctx = NULL; + + if (ac) { + rspamd_redis_pool_release_connection(ud->pool, ac, + RSPAMD_REDIS_RELEASE_FATAL); + } + } REDIS_RELEASE(ctx); } -- 2.47.3