From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 7A1C91A3E264; Wed, 25 Feb 2026 14:56:54 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 7A1C91A3E264 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1772020614; bh=xoJMc416C1Xyvql2Vl5/JvzhkQibbyceZUTCcthFuMw=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=SVZ5mXU5PchRwj8ISLq0Hy0AWeNeLXEHtczoFpk8zQKnW9fhxQ6AlnR5OXdURwjrL eIP2Es/zQrh0Y9a29iAberWF3ScdI3SaMZ2xQ6gsSlqnsAbjL1u3odaIdUZYaQzYgk w8KHz4s6ScKr/7PEcF680fgvQ6gSKhzkLhhO6FN8= Received: from send35.i.mail.ru (send35.i.mail.ru [89.221.237.130]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 9699E1A3E264 for ; Wed, 25 Feb 2026 14:56:52 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 9699E1A3E264 Received: by exim-smtp-64fd7cf497-cts56 with esmtpa (envelope-from ) id 1vvDVb-00000000Ax0-2PFR; Wed, 25 Feb 2026 14:56:51 +0300 To: Sergey Bronnikov Date: Wed, 25 Feb 2026 14:57:39 +0300 Message-ID: <20260225115740.13924-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9A6EFB945BF0DEAB2582A3CB12AD2B04C05E0E6BFF7843E3E182A05F538085040BE4CFC1245F325D13DE06ABAFEAF6705699ABC1CBF006C5CBC122EC78ECA4ECEDBFB7A5F7D7596DD X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE79683A3C835791080EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB55337566145F6DE9D17D49A83067AE2A1D59047D88B708418D8925A2898AA1F4BDC5AB08389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0B27420F9988F54058941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6AEEA5BB16A939343CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB8D32BA5DBAC0009BE9E8FC8737B5C22490E0E8EDE14C8C9B276E601842F6C81A12EF20D2F80756B5FB606B96278B59C4276E601842F6C81A127C277FBC8AE2E8B0A46EECFBE3927EE3AA81AA40904B5D99C9F4D5AE37F343AD1F44FA8B9022EA23BBE47FD9DD3FB595F5C1EE8F4F765FC72CEEB2601E22B093A03B725D353964B0B7D0EA88DDEDAC722CA9DD8327EE4930A3850AC1BE2E735837C4FEFBD186071C4224003CC83647689D4C264860C145E X-C1DE0DAB: 0D63561A33F958A500FB4C9B758AB1D15002B1117B3ED6969FE8E02B77BCA37BBFF4097FFC9E796F823CB91A9FED034534781492E4B8EEADF12279BA039A6965C79554A2A72441328621D336A7BC284946AD531847A6065A535571D14F44ED41 X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34C77DD89D51EBB774225B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D659921A7FD72394BD32F4EBBBA0B4C20EA2D8A09644F6A90B4C770F4C3C49B4C2E0FB7D97CC8FC89599B8341EE9D5BE9A0AD276930539E1FA5F8D5A8AA4B97602DDCE48A11B731FE95F6536EB022892E5344C41F94D744909CECFA6C6B0C050A61A8CAF69B82BA93681CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVbwN8XFWZxQU65sYCE6A01s= X-Mailru-Sender: 520A125C2F17F0B1A9638AD358559B59DC23DB7B493569BB3DE06ABAFEAF6705699ABC1CBF006C5CB7CBEF92542CD7C88B0A2698F12F5C9EC77752E0C033A69E86920BD37369036789A8C6A0E60D2BB63A5DB60FBEB33A8A0DA7A0AF5A3A8387 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] FFI: Avoid dangling cts->L. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mike Pall Reported by ZumiKua. (cherry picked from commit c94312d348e3530b369b4e517fce4c65df6cd270) When executing cdata finalizer on some lua_State, this state is set to `cts->L`. If the state will be GC-ed and freed later, this reference becomes dangling, so any FFI callback will use this invalid reference. This patch fixes it by setting `cts->L` to the `mainthread` on the destruction of the referenced one. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#12134 --- Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1405-dangling-cts-L Related issues: * https://github.com/LuaJIT/LuaJIT/issues/1405 * https://github.com/tarantool/tarantool/issues/12134 src/lj_state.c | 4 ++ test/tarantool-c-tests/CMakeLists.txt | 2 + .../lj-1405-dangling-cts-L.test.c | 72 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 test/tarantool-c-tests/lj-1405-dangling-cts-L.test.c diff --git a/src/lj_state.c b/src/lj_state.c index 053e5ec9..2eec5857 100644 --- a/src/lj_state.c +++ b/src/lj_state.c @@ -360,6 +360,10 @@ void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) lj_assertG(L != mainthread(g), "free of main thread"); if (obj2gco(L) == gcref(g->cur_L)) setgcrefnull(g->cur_L); +#if LJ_HASFFI + if (ctype_ctsG(g) && ctype_ctsG(g)->L == L) /* Avoid dangling cts->L. */ + ctype_ctsG(g)->L = mainthread(g); +#endif lj_func_closeuv(L, tvref(L->stack)); lj_assertG(gcref(L->openupval) == NULL, "stale open upvalues"); lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); diff --git a/test/tarantool-c-tests/CMakeLists.txt b/test/tarantool-c-tests/CMakeLists.txt index 32a8add0..3bb20bff 100644 --- a/test/tarantool-c-tests/CMakeLists.txt +++ b/test/tarantool-c-tests/CMakeLists.txt @@ -59,6 +59,8 @@ foreach(test_source ${tests}) OUTPUT_NAME "${exe}${C_TEST_SUFFIX}" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) + # Allow to call non-static functions via FFI. + target_link_options(${exe} PRIVATE "-rdynamic") target_link_libraries(${exe} libtest ${LUAJIT_LIBRARY}) add_dependencies(tarantool-c-tests-build ${exe}) diff --git a/test/tarantool-c-tests/lj-1405-dangling-cts-L.test.c b/test/tarantool-c-tests/lj-1405-dangling-cts-L.test.c new file mode 100644 index 00000000..b4ed4970 --- /dev/null +++ b/test/tarantool-c-tests/lj-1405-dangling-cts-L.test.c @@ -0,0 +1,72 @@ +#include "lua.h" + +#include "test.h" +#include "utils.h" + +/* XXX: Still need normal assert inside `call_callback()`. */ +#undef NDEBUG +#include + +typedef void (*callback_t)(void); +static callback_t callback = NULL; + +/* Function to be called via FFI. */ +extern void add_callback(callback_t cb) +{ + callback = cb; +} + +static void call_callback(void) +{ + assert(callback != NULL); + callback(); +} + +static int dangling_cts_L(void *test_state) +{ + lua_State *L = utils_lua_init(); + luaopen_ffi(L); + const char code[] = { + " local ffi = require('ffi') \n" \ + " ffi.cdef [[ \n" \ + " struct test { int a; }; \n" \ + " void add_callback(void (*cb)(void a)); \n" \ + /* Simple finalizer, nop. */ + " int getpid(void); \n" \ + " ]] \n" \ + " \n" \ + " local C = ffi.C \n" \ + " \n" \ + " local function nop() end \n" \ + /* Collected later. Set `cts->L` in the finalizer. */ + " ffi.gc(ffi.new('struct test'), C.getpid); \n" \ + /* Callback to be called on the old `cts->L`. */ + " C.add_callback(ffi.cast('void (*)(void)', nop)) \n" + }; + if (luaL_dostring(L, code) != LUA_OK) { + test_comment("error running Lua chunk: %s", + lua_tostring(L, -1)); + bail_out("error running Lua chunk"); + } + lua_State* newL = lua_newthread(L); + /* Remove `newL` from `L`. */ + lua_pop(L, 1); + /* Set `cts->L = newL` in the finalizer. */ + lua_gc(newL, LUA_GCCOLLECT, 0); + /* Just to be sure we don't use it anymore. */ + newL = NULL; + /* Collect `newL`. */ + lua_gc(L, LUA_GCCOLLECT, 0); + /* Use after free before the patch. */ + call_callback(); + utils_lua_close(L); + return TEST_EXIT_SUCCESS; +} + +int main(void) +{ + const struct test_unit tgroup[] = { + test_unit_def(dangling_cts_L), + }; + return test_run_group(tgroup, NULL); +} -- 2.53.0