From: Vsevolod Stakhov Date: Thu, 29 Jan 2026 15:17:15 +0000 (+0000) Subject: [Fix] lua_redis: add defensive check in GC handler X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e753e063c2102d920b8b2ea15f675de04b1aaa99;p=thirdparty%2Frspamd.git [Fix] lua_redis: add defensive check in GC handler Add validation in lua_redis_gc to check that the context pointer appears valid before releasing. This prevents crashes when Lua GC collects stale userdata pointing to already-freed memory. --- diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 214f6433ed..b1c29f9391 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -246,10 +246,24 @@ lua_redis_dtor(struct lua_redis_ctx *ctx) static int lua_redis_gc(lua_State *L) { - struct lua_redis_ctx *ctx = lua_check_redis(L, 1); + void *ud = rspamd_lua_check_udata(L, 1, rspamd_redis_classname); - if (ctx) { - REDIS_RELEASE(ctx); + if (ud) { + struct lua_redis_ctx **pctx = (struct lua_redis_ctx **) ud; + struct lua_redis_ctx *ctx = *pctx; + + /* + * Defensive check: verify the context appears valid before releasing. + * The context might be freed by another code path while this userdata + * still holds a pointer to it. Check that the destructor matches and + * refcount is reasonable to detect garbage/freed memory. + */ + if (ctx && ctx->ref.dtor == (ref_dtor_cb_t) lua_redis_dtor && + ctx->ref.refcount > 0 && ctx->ref.refcount < 10000) { + REDIS_RELEASE(ctx); + } + + *pctx = NULL; } return 0;