LuaJIT / LuaJIT

Mirror of the LuaJIT git repository
http://luajit.org
Other
4.71k stars 969 forks source link

Dangling CType reference in `carith_checkarg()` #1108

Closed Buristan closed 1 year ago

Buristan commented 1 year ago

This issue is the follow-up for the #920 (precisely for the commit cc96ab9d): it fixes the issue for the reallocation during trace recording but not for the reallocation during the metamethod call.

Reproducer for the issue: Build LuaJIT with `-DLUAJIT_CTYPE_CHECK_ANCHOR`: ```sh src/luajit -e " local ffi = require('ffi') ffi.cdef[[ int malloc(void); int fprintf(void); int printf(void); int memset(void); int memcpy(void); int memmove(void); int getppid(void); ]] local cfunc_type = ffi.metatype(ffi.typeof('struct {int a;}'), { __add = function(o1, o2) return o1 end }) local test = cfunc_type(1) -- Align cts->top. local _ = ffi.new('struct {int a; long b; float c;}', 0) -- Anchor table to prevent cdata objects from being collected. local anchor = {} local function save_new_func(func) anchor[#anchor + 1] = ffi.cast('void (*)(void)', func) end save_new_func(ffi.C.fprintf) save_new_func(ffi.C.printf) save_new_func(ffi.C.memset) save_new_func(ffi.C.memcpy) save_new_func(ffi.C.memmove) save_new_func(ffi.C.malloc) assert(ffi.typeinfo(127), 'cts->top >= 127') assert(not ffi.typeinfo(128), 'cts->top < 128') local res = test + ffi.C.getppid " LuaJIT ASSERT lj_cconv.c:136: lj_cconv_ct_ct: bad size for number type Aborted (core dumped) ```

The fix is the same:

diff --git a/src/lj_carith.c b/src/lj_carith.c
index df5f801e..b9679ba4 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -44,9 +44,14 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca)
         p = (uint8_t *)cdata_getptr(p, ct->size);
         if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
       } else if (ctype_isfunc(ct->info)) {
+        CTypeID id0 = i ? ctype_typeid(cts, ca->ct[0]) : 0;
         p = (uint8_t *)*(void **)p;
         ct = ctype_get(cts,
           lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|id), CTSIZE_PTR));
+        if (i) {
+          /* cts->tab may have been reallocated. */
+          ca->ct[0] = ctype_get(cts, id0);
+        }
       }
       if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
       ca->ct[i] = ct;
MikePall commented 1 year ago

Fixed. Thanks!