浏览代码

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.)
Roberto Ierusalimschy 4 月之前
父节点
当前提交
983bc433e6
共有 2 个文件被更改,包括 16 次插入0 次删除
  1. 3 0
      lvm.c
  2. 13 0
      testes/events.lua

+ 3 - 0
lvm.c

@@ -339,7 +339,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
       lua_assert(isempty(slot));  /* slot must be empty */
       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, slot, val);  /* set new value */
+        L->top.p--;
         invalidateTMcache(h);
         luaC_barrierback(L, obj2gco(h), val);
         return;

+ 13 - 0
testes/events.lua

@@ -370,6 +370,19 @@ x = 0 .."a".."b"..c..d.."e".."f".."g"
 assert(x.val == "0abcdefg")
 
 
+do
+  -- bug since 5.4.1
+  local mt = setmetatable({__newindex={}}, {__mode='v'})
+  local t = setmetatable({}, mt)
+
+  if T then T.allocfailnext() end
+
+  -- seg. fault
+  for i=1, 10 do t[i] = 1 end
+end
+
+
+
 -- concat metamethod x numbers (bug in 5.1.1)
 c = {}
 local x