aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-03-13 15:30:52 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-03-13 15:30:52 -0300
commit22974326ca0d4f893849ce722cc1d65b3e228f42 (patch)
tree1b4cb2cad1c55edce63e9fe6e468b1833950397d
parentc931d86e98da320c71da70c16d44aa28e9755520 (diff)
downloadlua-22974326ca0d4f893849ce722cc1d65b3e228f42.tar.gz
lua-22974326ca0d4f893849ce722cc1d65b3e228f42.tar.bz2
lua-22974326ca0d4f893849ce722cc1d65b3e228f42.zip
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.)
-rw-r--r--lapi.c5
-rw-r--r--lvm.c8
-rw-r--r--testes/events.lua13
3 files changed, 25 insertions, 1 deletions
diff --git a/lapi.c b/lapi.c
index a5e94507..eab12cac 100644
--- a/lapi.c
+++ b/lapi.c
@@ -681,6 +681,11 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
681} 681}
682 682
683 683
684/*
685** The following function assumes that the registry cannot be a weak
686** table, so that en mergency collection while using the global table
687** cannot collect it.
688*/
684static void getGlobalTable (lua_State *L, TValue *gt) { 689static void getGlobalTable (lua_State *L, TValue *gt) {
685 Table *registry = hvalue(&G(L)->l_registry); 690 Table *registry = hvalue(&G(L)->l_registry);
686 lu_byte tag = luaH_getint(registry, LUA_RIDX_GLOBALS, gt); 691 lu_byte tag = luaH_getint(registry, LUA_RIDX_GLOBALS, gt);
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,
325 325
326/* 326/*
327** Finish a table assignment 't[key] = val'. 327** Finish a table assignment 't[key] = val'.
328** About anchoring the table before the call to 'luaH_finishset':
329** This call may trigger an emergency collection. When loop>0,
330** the table being acessed is a field in some metatable. If this
331** metatable is weak and the table is not anchored, this collection
332** could collect that table while it is being updated.
328*/ 333*/
329void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 334void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
330 TValue *val, int hres) { 335 TValue *val, int hres) {
@@ -335,7 +340,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
335 Table *h = hvalue(t); /* save 't' table */ 340 Table *h = hvalue(t); /* save 't' table */
336 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 341 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
337 if (tm == NULL) { /* no metamethod? */ 342 if (tm == NULL) { /* no metamethod? */
343 sethvalue2s(L, L->top.p, h); /* anchor 't' */
344 L->top.p++; /* assume EXTRA_STACK */
338 luaH_finishset(L, h, key, val, hres); /* set new value */ 345 luaH_finishset(L, h, key, val, hres); /* set new value */
346 L->top.p--;
339 invalidateTMcache(h); 347 invalidateTMcache(h);
340 luaC_barrierback(L, obj2gco(h), val); 348 luaC_barrierback(L, obj2gco(h), val);
341 return; 349 return;
diff --git a/testes/events.lua b/testes/events.lua
index 2500fbd5..7e434b1f 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -379,6 +379,17 @@ x = 0 .."a".."b"..c..d.."e".."f".."g"
379assert(x.val == "0abcdefg") 379assert(x.val == "0abcdefg")
380 380
381 381
382do
383 -- bug since 5.4.1 (test needs T)
384 local mt = setmetatable({__newindex={}}, {__mode='v'})
385 local t = setmetatable({}, mt)
386
387 if T then T.allocfailnext() end
388
389 -- seg. fault
390 for i=1, 10 do t[i] = 1 end
391end
392
382-- concat metamethod x numbers (bug in 5.1.1) 393-- concat metamethod x numbers (bug in 5.1.1)
383c = {} 394c = {}
384local x 395local x
@@ -481,7 +492,7 @@ assert(not pcall(function (a,b) return a[b] end, a, 10))
481assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true)) 492assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true))
482 493
483-- bug in 5.1 494-- bug in 5.1
484T, K, V = nil 495local T, K, V = nil
485grandparent = {} 496grandparent = {}
486grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end 497grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end
487 498