]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Fix unsinking of IR_FSTORE for NULL metatable.
authorMike Pall <mike>
Tue, 23 Jan 2024 17:58:52 +0000 (18:58 +0100)
committerMike Pall <mike>
Tue, 23 Jan 2024 17:58:52 +0000 (18:58 +0100)
Reported by pwnhacker0x18. #1147

src/lj_snap.c

index b387dd76cfd68f8a4b89300a29bf86c6843d9ea0..4a77304873845e67d45eeae43542a6524c9707f0 100644 (file)
@@ -412,6 +412,7 @@ static TRef snap_replay_const(jit_State *J, IRIns *ir)
   case IR_KNUM: return lj_ir_k64(J, IR_KNUM, ir_knum(ir));
   case IR_KINT64: return lj_ir_k64(J, IR_KINT64, ir_kint64(ir));
   case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir));  /* Continuation. */
+  case IR_KNULL: return lj_ir_knull(J, irt_type(ir->t));
   default: lua_assert(0); return TREF_NIL; break;
   }
 }
@@ -821,9 +822,13 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex,
        if (irk->o == IR_FREF) {
          switch (irk->op2) {
          case IRFL_TAB_META:
-           snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
-           /* NOBARRIER: The table is new (marked white). */
-           setgcref(t->metatable, obj2gco(tabV(&tmp)));
+           if (T->ir[irs->op2].o == IR_KNULL) {
+             setgcrefnull(t->metatable);
+           } else {
+             snap_restoreval(J, T, ex, snapno, rfilt, irs->op2, &tmp);
+             /* NOBARRIER: The table is new (marked white). */
+             setgcref(t->metatable, obj2gco(tabV(&tmp)));
+           }
            break;
          case IRFL_TAB_NOMM:
            /* Negative metamethod cache invalidated by lj_tab_set() below. */