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 CDB1666C07F; Mon, 23 Oct 2023 12:29:38 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CDB1666C07F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1698053378; bh=Bq4/vwa9ds8tUqlv7qBjoagzZqDAEK5CsQXBcuw27Ys=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=N/uioEdgDceR3Z7+IATEMFpU0s+qNBvl3fm9spd5qi4b9pM7POrsqIL9p33LHSrqi QfroQm2Peh5U1IWUO7B8lSKOeSZS6oaByON1H3rvynf9QN7MYlBlKC1PDTPQHrwMWT nRHd2UmLMCc9rn8mht0r81Xml9KAU8QAECE2LtZE= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id DDCC867396A for ; Mon, 23 Oct 2023 12:26:41 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org DDCC867396A Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1qurCq-0007cl-Pz; Mon, 23 Oct 2023 12:26:41 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Mon, 23 Oct 2023 12:22:06 +0300 Message-ID: <33a9a2fc1efb801bfd5b8101be16755f2b394293.1698049570.git.skaplun@tarantool.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD9C197A170B57C5E433214076C7295A72B7A923EBE5E68280500894C459B0CD1B9A8EDA45BA5F1D1E6D2159B855B3B285808F89D8EC0FEE90F94E1874F75D17E7B X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7F8E53417176C7207EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637C05E8F374EA5A79AEA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38BE5CCB53A13BC8DBAFBFCD545E6BF9C2D99BC539A746D539DCC7F00164DA146DAFE8445B8C89999728AA50765F79006375FFD5C25497261569FA2833FD35BB23D2EF20D2F80756B5F868A13BD56FB6657A471835C12D1D977725E5C173C3A84C353FA85A707D24CADCC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CFE97D2AE7161E217F1DD303D21008E298D5E8D9A59859A8B6D082881546D9349175ECD9A6C639B01B78DA827A17800CE760822658196F8C5A731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A5109B8CF2E5580502F5A1C08BD931AD5FCE24C732048F8988F87CCE6106E1FC07E67D4AC08A07B9B0F254576263B31EA99C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF3FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF51074270A548147B06CEA9DC1DFF651C5EABBAAFD05F7E03E61D61D9E4D91A122D55A8303E10F658A8B50B9382ADB12A3EEC3752D6DB404B81A6637BD2AC01CBA74DFFEFA5DC0E7F02C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojqlVu258LHAEBrnqyF1+zZA== X-DA7885C5: 47069B95D9A26DD67C62A0077695275C5A3D4FEC8BFDA30C4DC96490E912EF7A262E2D401490A4A0DB037EFA58388B346E8BC1A9835FDE71 X-Mailru-Sender: 689FA8AB762F73930F533AC2B33E986BB65D9C84C3CCA245A1CBC6EB8AD4AF010FBE9A32752B8C9C2AA642CC12EC09F1FB559BB5D741EB962F61BD320559CF1EFD657A8799238ED55FEEDEB644C299C0ED14614B50AE0675 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 6/6] FFI: Fix dangling reference to CType in carith_checkarg(). 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 Sergey Kaplun. (cherry-picked from commit db944b2b56c86fcf133745976763604d96110285) During of an arithmetic operation with a cdata function object and some cdata value in `carith_checkarg()`, reallocation of `cts->tab` in `lj_ctype_intern()` may occur. In that case, the reference to the first `CType` object (`ca->ct[0]`) becomes invalid. This patch saves the `CTypeID` of this object and gets its `CType` again after possible reallocation. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#9145 --- src/lj_carith.c | 4 ++ ...8-fix-dangling-reference-to-ctype.test.lua | 67 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 test/tarantool-tests/lj-1108-fix-dangling-reference-to-ctype.test.lua diff --git a/src/lj_carith.c b/src/lj_carith.c index 4ae1e9ee..4e1d450a 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c @@ -44,9 +44,13 @@ 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; diff --git a/test/tarantool-tests/lj-1108-fix-dangling-reference-to-ctype.test.lua b/test/tarantool-tests/lj-1108-fix-dangling-reference-to-ctype.test.lua new file mode 100644 index 00000000..43a39886 --- /dev/null +++ b/test/tarantool-tests/lj-1108-fix-dangling-reference-to-ctype.test.lua @@ -0,0 +1,67 @@ +local tap = require('tap') +local ffi = require('ffi') +local test = tap.test('lj-1108-fix-dangling-reference-to-ctype'):skipcond({ + -- luacheck: no global + ['Impossible to predict the value of cts->top'] = _TARANTOOL, +}) + +test:plan(1) + +-- This test demonstrates LuaJIT's incorrect behaviour when the +-- reallocation of `cts->tab` strikes during the arithmetic cdata +-- metamethod. +-- The test fails under ASAN. + +-- XXX: Just some C functions to be casted. There is no need to +-- declare their prototypes correctly. +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;}'), { + -- Just some metatable with reloaded arithmetic operator. + __add = function(o1, _) return o1 end +}) +-- Just some cdata with metamethod. +local test_value = cfunc_type(1) + +-- XXX: structure to set `cts->top` to 112. +local _ = ffi.new('struct {int a; long b; float c; double d;}', 0) + +-- Anchor table to prevent cdata objects from being collected. +local anchor = {} +-- Each call to this function grows `cts->top` by 3. +local function save_new_func(func) + anchor[#anchor + 1] = ffi.cast('void (*)(void)', func) +end + +save_new_func(ffi.C.fprintf) -- `cts->top` = 112 +save_new_func(ffi.C.printf) -- `cts->top` = 115 +save_new_func(ffi.C.memset) -- `cts->top` = 118 +save_new_func(ffi.C.memcpy) -- `cts->top` = 121 +save_new_func(ffi.C.malloc) -- `cts->top` = 124 + +-- Assertions to check the `cts->top` value and step between +-- calls. +assert(ffi.typeinfo(124), 'cts->top >= 124') +assert(not ffi.typeinfo(125), 'cts->top < 125') + +save_new_func(ffi.C.memmove) -- `cts->top` = 127 + +assert(ffi.typeinfo(127), 'cts->top >= 127') +assert(not ffi.typeinfo(128), 'cts->top < 128') + +-- Just check cdata arith metamethod. The function argument should +-- be the second because dangling reference is the CType of the +-- first argumnent. +_ = test_value + ffi.C.getppid + +test:ok(true, 'no heap-use-after-free in carith_checkarg') + +test:done(true) -- 2.42.0