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 97E4172E60; Tue, 10 Jun 2025 18:59:51 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 97E4172E60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1749571191; bh=Mf+A3DF4KbyoncscxwCgR6vMgj/z9c9bgxtve1ibTpE=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=g6auprd6kPVHAJ4scseqbcmfh8DIbDnruVEuYTpVDkGYSnQhpFVY3o4nCiI/e3eOw UBD9to57f8FKvoqBKkF1Aatmqw3c3+389ilpeJeq/4w2Muomgf6964BFgMa3myt7iA EmLTLuPC6eQTamNo7OMujBB/IJ9fOR5SwjZ2MlZE= Received: from send175.i.mail.ru (send175.i.mail.ru [95.163.59.14]) (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 5886772E60 for ; Tue, 10 Jun 2025 18:59:50 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 5886772E60 Received: by exim-smtp-85b97957d7-cdqcv with esmtpa (envelope-from ) id 1uP1O9-00000000OQ2-13nZ; Tue, 10 Jun 2025 18:59:49 +0300 To: Sergey Bronnikov Date: Tue, 10 Jun 2025 18:59:47 +0300 Message-ID: <20250610155947.27340-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD909B82214CC9889170982F84AD7B1E438E800AB8DE742516300894C459B0CD1B95ABAE15FD83A66A605B18F8CB88C7B492B7AE867B1058741854E64C172939F1031E418E160CADA48 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7C2204D4F9A221771EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB553375668906014A252870FCE018A084D11C897F4039E6B3931C87EAB6C91D9079BDB7AD389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0565C7A4E90E531F78941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6042F1592492B88C6CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE72F88032165008D51731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A55AC8170D9F9E13B05002B1117B3ED6964EE9C8B6B79DB70B5D145BB8EF0DE66B823CB91A9FED034534781492E4B8EEADADEF88395FA75C5FC79554A2A72441328621D336A7BC284946AD531847A6065A535571D14F44ED41 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF66C8CCB481E928578A835AF6AC44D4AD9F9AC7A401F7959C5D3D47D3193DD0736238D603D2F19CCF1D3122CD40B080D24AF182F8B5E84F86FDE25EF5D43A5D57F1497831AAB54D295F4332CA8FE04980913E6812662D5F2A5EAB5682573093F7837F15F2B5E4A70B33F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVSykAyseJQ6/MCesBt+M+zE= X-DA7885C5: 3309FBE32AA1B53DF255D290C0D534F98147F799E14A04D29AB2DF6E6CB89451C2D7C880BDF4E85C5B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393FE9E42A757851DB641BCBF3CF93A7BE610A55CC2933819EC8F4B8B60895270F7E49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] Fix error generation in load*. 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 e76bb50d44702f601ec5dd167b03b475ed53860c) The chunkname pointer to the "@filename" is put on the Lua stack before the `lua_loadx()` and is removed right before the next `lua_pushfstring()` in case of the error. If the GC takes the step right at this moment inside `lua_pushfstring()` the string may be collected, and the next read from this `chunkname + 1` is from the deallocated memory. This patch fixes this by using the source string (or the constant one) instead. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#11278 --- Related issues: * https://github.com/LuaJIT/LuaJIT/issues/1353 * https://github.com/tarantool/tarantool/issues/11278 Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1353-loadfile-err-use-after-free src/lj_load.c | 3 +- ...-1353-loadfile-err-use-after-free.test.lua | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/tarantool-tests/lj-1353-loadfile-err-use-after-free.test.lua diff --git a/src/lj_load.c b/src/lj_load.c index fdbc54cb..205686bb 100644 --- a/src/lj_load.c +++ b/src/lj_load.c @@ -108,8 +108,9 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename, copyTV(L, L->top-1, L->top); } if (err) { + const char *fname = filename ? filename : "stdin"; L->top--; - lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(err)); + lua_pushfstring(L, "cannot read %s: %s", fname, strerror(err)); return LUA_ERRFILE; } return status; diff --git a/test/tarantool-tests/lj-1353-loadfile-err-use-after-free.test.lua b/test/tarantool-tests/lj-1353-loadfile-err-use-after-free.test.lua new file mode 100644 index 00000000..3aa02f3b --- /dev/null +++ b/test/tarantool-tests/lj-1353-loadfile-err-use-after-free.test.lua @@ -0,0 +1,39 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT use-after-free in case of the +-- error in `loadfile()`. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1353. +local test = tap.test('lj-1353-loadfile-err-use-after-free'):skipcond({ + ['Too many GC objects on start'] = _TARANTOOL, +}) + +test:plan(1) + +-- Determine the GC step size to finish the GC cycle in one step. +local full_step = 1 +while true do + collectgarbage('collect') + collectgarbage('setpause', 0) + collectgarbage('setstepmul', full_step) + if collectgarbage('step') then break end + full_step = full_step + 1 +end + +-- Check all possible GC step sizes. +for i = 1, full_step do + collectgarbage('collect') + collectgarbage('setpause', 0) + collectgarbage('setstepmul', i) + repeat + -- On Linux-like systems this always returns `nil`, with the + -- error: "cannot read .: Is a directory" + -- The string for the filename "@." may be collected during + -- the call, and later the pointer to the "." from that string + -- is used after the string is free. + loadfile('.') + until collectgarbage('step') +end + +test:ok(true, 'no use-after-free error') + +test:done(true) -- 2.49.0