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 2BF39A61F51; Tue, 26 Mar 2024 18:29:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 2BF39A61F51 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1711466977; bh=IMgRne1MAfPedNREdjwUBjXNqa2fUt4dbM7M7OYuBn0=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=yHdgP2r/c4v9+fMLOyqCYe/N3dPTOe64gBDYUpcMzr/J6ULk3fZpZjOA1MT9lBlNp l24SARJeYJiXiZCpdPtj2PL6jEeBi7Vzra7FEpx5Lw1ODvravTiCgNczL2JedjslsL UX991UgSptXYWXmUKQ4bPnQWUrZtsDJGbkCsyJ1U= Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 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 55A5BA61F4F for ; Tue, 26 Mar 2024 18:29:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 55A5BA61F4F Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-51381021af1so8577058e87.0 for ; Tue, 26 Mar 2024 08:29:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711466975; x=1712071775; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ku+vCXCxA5iryxf0jYqysrxz68x3p7gVTR9dlg5YirU=; b=a3/y4cL3ZiD5YC6BGeUvadDtyL7GJtFC+ep8kYAeVvioEiYg5O6BWdIevl+15pgfyN IWyoM4LXADqmF9vwGeQgaSz545WexHp9M5anlhraEFi9CGnPhZusWuh/Ss7J2EJdqqY9 pOJ6+tPuwHY9MlVgRbPNnElKx/u9SUe7wxqfJpK1jL+ITLtrd31OJm+mxyWiKNSx9wvR zLvDHcHziu9CJbSd6Nhe0bAOJABTLQBJaA6Ht0mu1mdgQeRi2k3MiwsuNKhxAthZ3gHI rxl6ncXg+S7g0h4mLLwUQwuyy8E0xkNcn8h9/khla57JBnPdg6TejwAcNaxNSKLvrSUs hEgQ== X-Gm-Message-State: AOJu0YwWZTeG5hTddZ+XqJqB5pD3pyvAKsEh5Y3sdLRn+6SQ/Gfv7KmQ ThMguOr55e5TptzQ/WlACMkiscHbN+jnBiFyH1zXBgoK18mFvoJ9acewTYPD X-Google-Smtp-Source: AGHT+IGQh74oQs4DZ6k2cNPsbbU/Y3MyMbx5GLsHuYiKbjDUYIfIWvNi2VmyDbM/c4/64t+ppd6qow== X-Received: by 2002:ac2:499e:0:b0:515:7686:6068 with SMTP id f30-20020ac2499e000000b0051576866068mr6457352lfl.55.1711466974942; Tue, 26 Mar 2024 08:29:34 -0700 (PDT) Received: from pony.. ([5.181.62.126]) by smtp.gmail.com with ESMTPSA id x8-20020a056512078800b00513c82518fasm1531920lfr.223.2024.03.26.08.29.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Mar 2024 08:29:34 -0700 (PDT) To: tarantool-patches@dev.tarantool.org, Sergey Kaplun , Maxim Kokryashkin Date: Tue, 26 Mar 2024 18:29:11 +0300 Message-Id: <3bd73ab3f3a0e8b200c493ec09e65f5ecb711a6b.1711466825.git.sergeyb@tarantool.org> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH luajit] Prevent loop in snap_usedef(). 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 Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Sergey Bronnikov Reported by XmiliaH. (cherry picked from commit 0e66fc96377853d898390f1a02723c54ec3a42f7) It is possible to get an infinite loop in a function `snap_usedef` when a `UCLO` makes a tight loop. Sergey Bronnikov: * added the description and the test for the problem Part of tarantool/tarantool#9595 --- Branch: https://github.com/tarantool/luajit/tree/ligurio/lj-736-prevent-loop-in-snap_usedef Issues: - https://github.com/LuaJIT/LuaJIT/issues/736 - https://github.com/tarantool/tarantool/issues/9595 src/lj_snap.c | 7 ++- .../lj-736-BC_UCLO-triggers-infinite-loop.lua | 59 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 test/tarantool-tests/lj-736-BC_UCLO-triggers-infinite-loop.lua diff --git a/src/lj_snap.c b/src/lj_snap.c index 5a00b5cd..0710e1f0 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c @@ -252,7 +252,12 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, BCReg minslot = bc_a(ins); if (op >= BC_FORI && op <= BC_JFORL) minslot += FORL_EXT; else if (op >= BC_ITERL && op <= BC_JITERL) minslot += bc_b(pc[-2])-1; - else if (op == BC_UCLO) { pc += bc_j(ins); break; } + else if (op == BC_UCLO) { + ptrdiff_t delta = bc_j(ins); + if (delta < 0) return maxslot; /* Prevent loop. */ + pc += delta; + break; + } for (s = minslot; s < maxslot; s++) DEF_SLOT(s); return minslot < maxslot ? minslot : maxslot; } diff --git a/test/tarantool-tests/lj-736-BC_UCLO-triggers-infinite-loop.lua b/test/tarantool-tests/lj-736-BC_UCLO-triggers-infinite-loop.lua new file mode 100644 index 00000000..28a2b61b --- /dev/null +++ b/test/tarantool-tests/lj-736-BC_UCLO-triggers-infinite-loop.lua @@ -0,0 +1,59 @@ +local tap = require('tap') +local test = tap.test('lj-736-BC_UCLO-triggers-infinite-loop'):skipcond({ + ['Test requires JIT enabled'] = not jit.status(), +}) + +test:plan(1) + +-- Test reproduces an issue when BC_UCLO triggers an infinite loop. +-- See details in https://github.com/LuaJIT/LuaJIT/issues/736. +-- +-- Listing below demonstrates a problem - +-- the bytecode UCLO on the line 13 makes a loop at 0013-0014: +-- +-- - BYTECODE -- bc_uclo.lua:0-20 +-- 0001 KPRI 0 0 +-- 0002 FNEW 1 0 ; bc_uclo.lua:5 +-- 0003 KSHORT 2 1 +-- 0004 KSHORT 3 4 +-- 0005 KSHORT 4 1 +-- 0006 FORI 2 => 0011 +-- 0007 => ISNEN 5 0 ; 2 +-- 0008 JMP 6 => 0010 +-- 0009 UCLO 0 => 0012 +-- 0010 => FORL 2 => 0007 +-- 0011 => UCLO 0 => 0012 +-- 0012 => KPRI 0 0 +-- 0013 UCLO 0 => 0012 +-- 0014 FNEW 1 1 ; bc_uclo.lua:18 +-- 0015 UCLO 0 => 0016 +-- 0016 => RET0 0 1 + +jit.opt.start('hotloop=1') + +do + local uv = 0 + local w = function() return uv end -- luacheck: no unused + for i = 1, 2 do + -- Infinite loop is here. + if i == 2 then + if i == 2 then + goto pass + end + goto unreachable + end + end +end + +::unreachable:: +-- Lua chunk below is required for reproducing a bug. +do + local uv = 0 -- luacheck: no unused + goto unreachable + local w = function() return uv end -- luacheck: ignore +end + +::pass:: + +test:ok(true, 'BC_UCLO does not trigger an infinite loop') +os.exit(test:check() and 0 or 1) -- 2.34.1