From 22974326ca0d4f893849ce722cc1d65b3e228f42 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 13 Mar 2025 15:30:52 -0300 Subject: Use after free in 'luaV_finishset' If a metatable is a weak table, its __newindex field could be collected by an emergency collection while being used in 'luaV_finishset'. (This bug has similarities with bug 5.3.2-1, fixed in commit a272fa66.) --- lvm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lvm.c') diff --git a/lvm.c b/lvm.c index f0e73f9b..af048d81 100644 --- a/lvm.c +++ b/lvm.c @@ -325,6 +325,11 @@ lu_byte luaV_finishget (lua_State *L, const TValue *t, TValue *key, /* ** Finish a table assignment 't[key] = val'. +** About anchoring the table before the call to 'luaH_finishset': +** This call may trigger an emergency collection. When loop>0, +** the table being acessed is a field in some metatable. If this +** metatable is weak and the table is not anchored, this collection +** could collect that table while it is being updated. */ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, TValue *val, int hres) { @@ -335,7 +340,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, Table *h = hvalue(t); /* save 't' table */ tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ if (tm == NULL) { /* no metamethod? */ + sethvalue2s(L, L->top.p, h); /* anchor 't' */ + L->top.p++; /* assume EXTRA_STACK */ luaH_finishset(L, h, key, val, hres); /* set new value */ + L->top.p--; invalidateTMcache(h); luaC_barrierback(L, obj2gco(h), val); return; -- cgit v1.2.3-55-g6feb