diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-13 15:42:39 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-13 15:42:39 -0300 |
| commit | 983bc433e6a60cbc4fe3a16f1d4713bacb8e3509 (patch) | |
| tree | 48e7e1349f29de673d5f78a9e0d55b369780c911 | |
| parent | 25da574fcbb68bf507431a6091ab73ac434c9428 (diff) | |
| download | lua-983bc433e6a60cbc4fe3a16f1d4713bacb8e3509.tar.gz lua-983bc433e6a60cbc4fe3a16f1d4713bacb8e3509.tar.bz2 lua-983bc433e6a60cbc4fe3a16f1d4713bacb8e3509.zip | |
Bug: 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-- | lvm.c | 3 | ||||
| -rw-r--r-- | testes/events.lua | 13 |
2 files changed, 16 insertions, 0 deletions
| @@ -339,7 +339,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
| 339 | lua_assert(isempty(slot)); /* slot must be empty */ | 339 | lua_assert(isempty(slot)); /* slot must be empty */ |
| 340 | tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ | 340 | tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ |
| 341 | if (tm == NULL) { /* no metamethod? */ | 341 | if (tm == NULL) { /* no metamethod? */ |
| 342 | sethvalue2s(L, L->top.p, h); /* anchor 't' */ | ||
| 343 | L->top.p++; /* assume EXTRA_STACK */ | ||
| 342 | luaH_finishset(L, h, key, slot, val); /* set new value */ | 344 | luaH_finishset(L, h, key, slot, val); /* set new value */ |
| 345 | L->top.p--; | ||
| 343 | invalidateTMcache(h); | 346 | invalidateTMcache(h); |
| 344 | luaC_barrierback(L, obj2gco(h), val); | 347 | luaC_barrierback(L, obj2gco(h), val); |
| 345 | return; | 348 | return; |
diff --git a/testes/events.lua b/testes/events.lua index 8d8563b9..def13dc8 100644 --- a/testes/events.lua +++ b/testes/events.lua | |||
| @@ -370,6 +370,19 @@ x = 0 .."a".."b"..c..d.."e".."f".."g" | |||
| 370 | assert(x.val == "0abcdefg") | 370 | assert(x.val == "0abcdefg") |
| 371 | 371 | ||
| 372 | 372 | ||
| 373 | do | ||
| 374 | -- bug since 5.4.1 | ||
| 375 | local mt = setmetatable({__newindex={}}, {__mode='v'}) | ||
| 376 | local t = setmetatable({}, mt) | ||
| 377 | |||
| 378 | if T then T.allocfailnext() end | ||
| 379 | |||
| 380 | -- seg. fault | ||
| 381 | for i=1, 10 do t[i] = 1 end | ||
| 382 | end | ||
| 383 | |||
| 384 | |||
| 385 | |||
| 373 | -- concat metamethod x numbers (bug in 5.1.1) | 386 | -- concat metamethod x numbers (bug in 5.1.1) |
| 374 | c = {} | 387 | c = {} |
| 375 | local x | 388 | local x |
