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 95054504BEF; Wed, 8 Nov 2023 11:45:19 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 95054504BEF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1699433119; bh=SnVWLLZKbncE5D3hxD1L5bu35ljZPGqttbMlO6AqJ4c=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=qDgfdnYSjMHMxeg5jQEdec2WsmDILQdfssEzC4WZ6GV8LuPRlXuhSiQIarqgTwh2c WF8UOJbwuij17W5tSU2r7Jcx9On28r7xCntz8TkdAXXOzw/u8dYR/rIR0eph4kKYy2 QUwcqdMESqj757bweacU0v4iRJJvqBnf6hgevKHQ= 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 45469504BEF for ; Wed, 8 Nov 2023 11:45:18 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 45469504BEF Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1r0eBZ-0000Yr-64; Wed, 08 Nov 2023 11:45:17 +0300 To: Maxim Kokryashkin , Igor Munkin , Sergey Bronnikov Date: Wed, 8 Nov 2023 11:40:44 +0300 Message-ID: <20231108084044.6654-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD99FFD3FA9E0A670D850CF0F3E82B2748177A15F699ADCD00600894C459B0CD1B9269584E208968B3EAC82C85463BF76535ACBD53592199F29AAF74BEEA48AC221 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE721B3E54BB37EA0B4EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063704DB3724D938F0238638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8737E58089F512E1165046DFAB3FE2261117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC55B19328CBC4F849A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751FF04B652EEC242312D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269176DF2183F8FC7C03E69C4AB24A3574568655334FD4449CB33AC447995A7AD1857739F23D657EF2BD5E8D9A59859A8B608F55DA9FB1C18C0089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: 0D63561A33F958A578D4214DB63E0BBA6CB99927A79D09C008614A52E06EBD9FF87CCE6106E1FC07E67D4AC08A07B9B04CB6874B0BCFF0B89C5DF10A05D560A950611B66E3DA6D700B0A020F03D25A0997E3FB2386030E77 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFD67BBC55E3B0D06770ABB98034E93506785C6D9368ECFBE9CEEAC7813251BAEA3D4CAFFB26F46A3D2B33B16BC67043E00D0CF150F34ADC62B335C0F44DBA0E2C461A413F07889F2102C26D483E81D6BE5EF9655DD6DEA7D65774BB76CC95456EEC5B5AD62611EEC62B5AFB4261A09AF0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojGx6zOZpnTNCnbpMoHccbaA== X-DA7885C5: 2E28C63B3B3847E6D86EC0D098456CD5B837F853F9C68E7E4CBC255F41D4040D262E2D401490A4A0DB037EFA58388B346E8BC1A9835FDE71 X-Mailru-Sender: 689FA8AB762F7393590D8C940224AE3377A9434CBCA40EF03F6FD0DC16C7B8330FBE9A32752B8C9C2AA642CC12EC09F1FB559BB5D741EB962F61BD320559CF1EFD657A8799238ED55FEEDEB644C299C0ED14614B50AE0675 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] FFI: Fix pragma push stack limit check and throw on 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 Sergey Kaplun. (cherry-picked from commit 433d7e8d8d182f44e88b5cfdc4b2d3026469dfb7) `cp->packstack` is the array of size `CPARSE_MAX_PACKSTACK` (7). Before the patch, `cp->curpack` is checked to be less than `CPARSE_MAX_PACKSTACK`, but then `cp->packstack` is accessed at `cp->curpack + 1`, which is out of bounds, so `cp->curpack` value is overwritten. This patch fixes a condition and also adds the error throw when counter is overflow (instead of rewriting a top `cp->packstack` value). Sergey Kaplun: * added the description and the test for the problem Resolves tarantool/tarantool#9339 Part of tarantool/tarantool#9145 --- Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1114-ffi-pragma-pack Tarantool PR: https://github.com/tarantool/tarantool/pull/9342 Relate issues: * https://github.com/LuaJIT/LuaJIT/issues/1114 * https://github.com/tarantool/tarantool/issues/9339 * https://github.com/tarantool/tarantool/issues/9145 src/lj_cparse.c | 4 +- .../lj-1114-ffi-pragma-pack.test.lua | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/tarantool-tests/lj-1114-ffi-pragma-pack.test.lua diff --git a/src/lj_cparse.c b/src/lj_cparse.c index 6d9490ca..01deb3bf 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c @@ -1777,9 +1777,11 @@ static void cp_pragma(CPState *cp, BCLine pragmaline) cp_check(cp, '('); if (cp->tok == CTOK_IDENT) { if (cp_str_is(cp->str, "push")) { - if (cp->curpack < CPARSE_MAX_PACKSTACK) { + if (cp->curpack < CPARSE_MAX_PACKSTACK-1) { cp->packstack[cp->curpack+1] = cp->packstack[cp->curpack]; cp->curpack++; + } else { + cp_errmsg(cp, cp->tok, LJ_ERR_XLEVELS); } } else if (cp_str_is(cp->str, "pop")) { if (cp->curpack > 0) cp->curpack--; diff --git a/test/tarantool-tests/lj-1114-ffi-pragma-pack.test.lua b/test/tarantool-tests/lj-1114-ffi-pragma-pack.test.lua new file mode 100644 index 00000000..e5642828 --- /dev/null +++ b/test/tarantool-tests/lj-1114-ffi-pragma-pack.test.lua @@ -0,0 +1,44 @@ +local tap = require('tap') + +-- Test file to demonstrate LuaJIT incorrect parsing of `#pragma` +-- directive via FFI. +-- See also: https://github.com/LuaJIT/LuaJIT/issues/1114. + +local test = tap.test('lj-1114-ffi-pragma-pack') +local ffi = require 'ffi' + +test:plan(2) + +-- `cp->packstack` is the array of size `CPARSE_MAX_PACKSTACK` +-- (7). Before the patch, `cp->curpack` is checked to be less than +-- `CPARSE_MAX_PACKSTACK`, but then `cp->packstack` is accessed at +-- `cp->curpack + 1`, which is out of bounds, so `cp->curpack` +-- value is overwritten. +-- As a result, the incorrect pack value (1) is chosen after pop. +-- After the patch, the error is thrown in the case of overflow +-- (instead of rewriting the top pack slot value), so we use the +-- wrapper to catch the error. +local function ffi_cdef_wp() + ffi.cdef[[ + #pragma pack(push, 1) + #pragma pack(push, 1) + #pragma pack(push, 1) + #pragma pack(push, 1) + #pragma pack(push, 8) + #pragma pack(push, 8) + #pragma pack(push, 8) + #pragma pack(pop) + struct aligned_struct {uint64_t a; uint8_t b;}; + ]] + + -- Got 9 in case of buffer overflow. + return ffi.sizeof(ffi.new('struct aligned_struct')) +end + +local err, msg = pcall(ffi_cdef_wp) + +test:ok(not err, 'the error is thrown when couner overflows') +test:like(msg, 'chunk has too many syntax levels', + 'the error message is correct') + +test:done(true) -- 2.42.0