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 BF64C13D8E9D; Tue, 10 Jun 2025 13:29:49 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org BF64C13D8E9D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1749551389; bh=eipvbCnfP7sdcgPpj8RdyJiLfzIPaliMEMgqoAxuA5c=; 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=yhOMVQNELegLK+eamBetNIgTlIng7U/3+19YqLXKGwhjzft/eevMLYvzvr+bOmVBq RRlBu/j6aoDS3dIgPNCQG8dYbH+DAoMASHWgbAMs9a/XM1dN/rl3Pxp9hLqwe7GSFw YIoU5GflRPWlmFGaCHR2nRNvfx7af+198ib+kMfc= Received: from send197.i.mail.ru (send197.i.mail.ru [95.163.59.36]) (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 72F9813D8E97 for ; Tue, 10 Jun 2025 13:28:49 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 72F9813D8E97 Received: by exim-smtp-85b97957d7-j7lvw with esmtpa (envelope-from ) id 1uOwDo-00000000RhL-2KH0; Tue, 10 Jun 2025 13:28:48 +0300 To: Sergey Bronnikov Date: Tue, 10 Jun 2025 13:28:52 +0300 Message-ID: <1152e27d618a4717c0f48cb77d085434eb183b18.1749550966.git.skaplun@tarantool.org> X-Mailer: git-send-email 2.49.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: 4F1203BC0FB41BD909B82214CC9889170A8AA6A0146904312CC2361CCB27B2BB00894C459B0CD1B99DC77D1558A7CF1503AAE3001806DF101C551F82E085234B23E79FF8DC8A0139F8D9167951636718 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7F2EC3597058CFA6DEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB5533756677AE571B3D4B003CF285DC458C661402401485CE70ED230449AA7EC73A691550389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0565C7A4E90E531F78941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6A0EE70D6C4970CA7A471835C12D1D977C4224003CC8364762BB6847A3DEAEFB0F43C7A68FF6260569E8FC8737B5C2249EC8D19AE6D49635B68655334FD4449CB9ECD01F8117BC8BEAAAE862A0553A39223F8577A6DFFEA7C3B6C7E47A292E8D043847C11F186F3C59DAA53EE0834AAEE X-C1DE0DAB: 0D63561A33F958A587D37233988392645002B1117B3ED696F979AFFAD74C918A4869453249F34FA4823CB91A9FED034534781492E4B8EEAD05E80F4396618BB2C79554A2A72441328621D336A7BC284946AD531847A6065A17B107DEF921CE79BDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF3FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF2A2EF63125EDBD2834487A484B79C1D15AEFD6F497D85C720903ED4D9166F6BD8DB4AB58792EC0EC078977F53EF84CDABE26000549CFD0420865C5267A8335FD9847B7E1F14157845F4332CA8FE04980913E6812662D5F2A5EAB5682573093F7837F15F2B5E4A70B33F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVSykAyseJQ6/onSdtviYK6A= X-DA7885C5: 2B57C3563621C92AF255D290C0D534F99B44F4199EA0AC299AB2DF6E6CB8943BF28F5C1C3018F06F5B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393FE9E42A757851DB6D6BCDF589319629ADD6B56B1E5A19E08D1CB0C8CD5315149E49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 2/2] Different fix for partial snapshot restore due to stack overflow. 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 Junlong Li. Fixed by Peter Cawley. (cherry picked from commit 86e7123bb1782a5f200ba5e83b8c4f3fbad4f7bc) This patch is a follow-up to the previous commit, which leads to a dirty read of the pseudo-valid PC set for the cframe on snapshot restoration. To avoid these dirty reads, this patch sets the PC to the outer frame as well before possible error throwing. Sergey Kaplun: * added the description and the test for the problem Part of tarantool/tarantool#11278 --- src/lj_snap.c | 3 +- src/lj_trace.c | 4 +- ...-1196-stack-overflow-snap-restore.test.lua | 65 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 test/tarantool-tests/lj-1196-stack-overflow-snap-restore.test.lua diff --git a/src/lj_snap.c b/src/lj_snap.c index 8d7bd868..4cfae579 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -955,7 +955,8 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) lua_State *L = J->L; /* Set interpreter PC to the next PC to get correct error messages. */ - setcframe_pc(cframe_raw(L->cframe), pc+1); + setcframe_pc(L->cframe, pc+1); + setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc); /* Make sure the stack is big enough for the slots from the snapshot. */ if (LJ_UNLIKELY(L->base + snap->topslot >= tvref(L->maxstack))) { diff --git a/src/lj_trace.c b/src/lj_trace.c index 8a18d3cf..0d1d233a 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -909,10 +909,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) exd.J = J; exd.exptr = exptr; errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp); - if (errcode) { - setcframe_pc(cframe_raw(L->cframe), L); /* Point to any valid memory. */ + if (errcode) return -errcode; /* Return negated error code. */ - } if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */ diff --git a/test/tarantool-tests/lj-1196-stack-overflow-snap-restore.test.lua b/test/tarantool-tests/lj-1196-stack-overflow-snap-restore.test.lua new file mode 100644 index 00000000..942d1f82 --- /dev/null +++ b/test/tarantool-tests/lj-1196-stack-overflow-snap-restore.test.lua @@ -0,0 +1,65 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT dirty reads after stack +-- overflow during restoration from the snapshot. +-- The test fails before the patch under Valgrind. +-- +-- luacheck: push no max_comment_line_length +-- +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1196, +-- https://www.freelists.org/post/luajit/Invalid-read-found-by-valgrind. +-- +-- luacheck: pop + +local test = tap.test('lj-1196-stack-overflow-snap-restore') + +test:plan(4) + +-- XXX: This file has the same tests as the +-- , but without disabling the +-- compilation for the given functions. Hence, the check here is +-- less strict -- we just check that there are no dirty reads, +-- uninitialized memory access, etc. + +local function recursive_f_noarg() + recursive_f_noarg() +end + +local function recursive_one_arg(argument) + recursive_one_arg(argument) +end + +local function recursive_f_vararg(...) + recursive_f_vararg(1, ...) +end + +local function recursive_f_vararg_tail(...) + return recursive_f_vararg_tail(1, ...) +end + +-- Use `coroutine.wrap()`, for independent stack sizes. +-- The invalid read is done by the error handler +-- `debug.traceback()`, since it observes the pseudo PC (`L`) and +-- reads the memory by `L - 4` address before the patch. + +coroutine.wrap(function() + local status = xpcall(recursive_f_noarg, debug.traceback) + test:ok(not status, 'correct status, recursive no arguments') +end)() + +coroutine.wrap(function() + local status = xpcall(recursive_one_arg, debug.traceback, 1) + test:ok(not status, 'correct status, recursive one argument') +end)() + +coroutine.wrap(function() + local status = xpcall(recursive_f_vararg, debug.traceback, 1) + test:ok(not status, 'correct status, recursive vararg') +end)() + +coroutine.wrap(function() + local status = xpcall(recursive_f_vararg_tail, debug.traceback, 1) + test:ok(not status, 'correct status, recursive vararg tail') +end)() + +test:done(true) -- 2.49.0