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 8BC58D40549; Tue, 17 Sep 2024 13:32:25 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 8BC58D40549 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1726569145; bh=MZYLXXXBfKi55h56BTDKkl9BJRQDg7/WXYgOPA9OgXM=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=u4/Hb3lKrlSfRdou/iloKXvs67N0dlid0yWvhg3VMp305K/MyQoXuIPBsYp6+WKqQ /zhNsDXaRDyTqcVJbIFxfllg0dQLEj/HyOTEgZ7g609i/HgGMDYot0GHP08bkaPK+6 9fGi+DpYhfXzAeYTOq7XJ7/t+BIYlGH3p3uNdQjw= Received: from smtp57.i.mail.ru (smtp57.i.mail.ru [95.163.41.95]) (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 1CFFBD40548 for ; Tue, 17 Sep 2024 13:32:25 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 1CFFBD40548 Received: by smtp57.i.mail.ru with esmtpa (envelope-from ) id 1sqVVP-0000000Coum-23YQ; Tue, 17 Sep 2024 13:32:24 +0300 Content-Type: multipart/alternative; boundary="------------EgLPmvTMHvnKG7pz6PoIU0vH" Message-ID: <8178af4b-fa35-44c2-b3fd-6e563eb660d5@tarantool.org> Date: Tue, 17 Sep 2024 13:32:23 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Maxim Kokryashkin Cc: tarantool-patches@dev.tarantool.org References: <20240826123740.12759-1-skaplun@tarantool.org> In-Reply-To: <20240826123740.12759-1-skaplun@tarantool.org> X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: EEAE043A70213CC8 X-77F55803: 4F1203BC0FB41BD96BD36BAB11CDBC530FB8B3B9B83BA94645948C5416F15F7A182A05F5380850404C228DA9ACA6FE2760ECCAABABFCD7AD0578E6996F383413E9DD69FFBF4F7ABC169C8E72D3CB868A8F23EFBB696E3500 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE77603ADE015AF816DEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637F0135404761DA3FC8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8C129C8CD65E92C012A50BF9F834C9A02576D3321A3EEB1B6CC7F00164DA146DAFE8445B8C89999728AA50765F7900637F6B57BC7E64490618DEB871D839B7333395957E7521B51C2DFABB839C843B9C08941B15DA834481F8AA50765F7900637BA939FD1B3BAB99B389733CBF5DBD5E9B5C8C57E37DE458BD9DD9810294C998ED8FC6C240DEA76428AA50765F79006370D3775E2C04069D5D81D268191BDAD3DBD4B6F7A4D31EC0BE2F48590F00D11D6D81D268191BDAD3D78DA827A17800CE7098A8CFB62EEFF4BEC76A7562686271ED91E3A1F190DE8FD2E808ACE2090B5E14AD6D5ED66289B5259CC434672EE63711DD303D21008E298D5E8D9A59859A8B6B372FE9A2E580EFC725E5C173C3A84C3045DD857D6FE754135872C767BF85DA2F004C90652538430E4A6367B16DE6309 X-C1DE0DAB: 0D63561A33F958A52412AC7584A4608A5002B1117B3ED69612385D876726E600B74D9144D44E4FCF823CB91A9FED034534781492E4B8EEADD0953842B444AAC3BDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF3FED46C3ACD6F73ED3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CF351C5BA87BD4D8AF51D55386695FE5D1C83C3B3DA52A04EA3559F16B9163C5C50FDE0425728830096C89B7A10C2A3D35BBEE6924DF0597A3371A99D909B15C88C2B4845275791D6B5F4332CA8FE04980913E6812662D5F2AB9AF64DB4688768036DF5FE9C0001AF333F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojK9mC3H63xFYs6adIrf5ZAQ== X-Mailru-Sender: 520A125C2F17F0B1E52FEF5D219D614095D27761119B9EF6A9AE2C1F1A91EF8B895DADFEEC7356D10152A3D17938EB451EB5A0BCEC6A560B3DDE9B364B0DF289BE2DA36745F2EEB5CEBA01FB949A1F1EEAB4BC95F72C04283CDA0F3B3F5B9367 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit] Fix limit check in narrow_conv_backprop(). 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" This is a multi-part message in MIME format. --------------EgLPmvTMHvnKG7pz6PoIU0vH Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi, Sergey, thanks for tha patch! LGTM with a minor comment below. On 26.08.2024 15:37, Sergey Kaplun wrote: > From: Mike Pall > > Thanks to Sergey Kaplun. > > (cherry picked from commit e45fd4cb713b610506213692f3b55a1869febb03) > > `narrow_conv_backprop()` misses the stack pointer (`nc->sp`) limit check > after a bunch of recursive calls that may change its value. As a result, > it leads to stack-buffer-overflow during the instruction narrowing. This > patch adds a missing check. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#10199 > --- > > Branch:https://github.com/tarantool/luajit/tree/skaplun/lj-1262-fix-limit-narrow-conv-backprop > Related issues: > *https://github.com/tarantool/tarantool/issues/10199 > *https://github.com/LuaJIT/LuaJIT/issues/1262 > > src/lj_opt_narrow.c | 3 +- > ...62-fix-limit-narrow-conv-backprop.test.lua | 61 +++++++++++++++++++ > 2 files changed, 63 insertions(+), 1 deletion(-) > create mode 100644 test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua > > diff --git a/src/lj_opt_narrow.c b/src/lj_opt_narrow.c > index db0da10f..6b6f20d3 100644 > --- a/src/lj_opt_narrow.c > +++ b/src/lj_opt_narrow.c > @@ -341,7 +341,8 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth) > NarrowIns *savesp = nc->sp; > int count = narrow_conv_backprop(nc, ir->op1, depth); > count += narrow_conv_backprop(nc, ir->op2, depth); > - if (count <= 1) { /* Limit total number of conversions. */ > + /* Limit total number of conversions. */ > + if (count <= 1 && nc->sp < nc->maxsp) { > *nc->sp++ = NARROWINS(IRT(ir->o, nc->t), ref); > return count; > } > diff --git a/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua b/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua > new file mode 100644 > index 00000000..6bb4025d > --- /dev/null > +++ b/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua > @@ -0,0 +1,61 @@ > +local tap = require('tap') > + > +-- Test file to demonstrate stack-buffer-overflow during the > +-- narrowing optimization. > +-- See also:https://github.com/LuaJIT/LuaJIT/issues/1262. > + > +local test = tap.test('lj-1262-fix-limit-narrow-conv-backprop'):skipcond({ > + ['Test requires JIT enabled'] = not jit.status(), > +}) > + > +test:plan(1) > + > +-- XXX: Test fails only under ASAN. > +-- XXX: The original reproducer was found by fuzzer: > +--https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=70779. > +-- It creates a long side trace with a huge amount of ADD IRs, > +-- which are recursively used in the `narrow_conv_backprop()` many > +-- enough times to catch the stack-buffer-overflow. I can't > +-- simplify the reproducer any more (or write it from scratch), so > +-- I leave it in that state. > + I would remove a sentence "I can't simplify the reproducer ..." from the test, because it is useful information on review and I think it is useless for those who will use the test. Feel free to ignore and leave as is. s/any more/anymore/ > +local DEFAULT_NUMBER = 1 > +local tonumber = tonumber > + > +local always_number = function(val) > + return tonumber(val) or DEFAULT_NUMBER > +end > + > +local add = function(v1, v2) > + return always_number(v1) + always_number(v2) > +end > + > +jit.opt.start('hotloop=1', 'hotexit=1') > + > +local counter_0 = 0 > +local counter_1 = 0 > +local counter_2 = 0 > +local tmp = add(nil, 'Name') > +local Name0 = add(tmp, 'Name') > +-- Start a long side trace here. > +for _ = 0, 0, 0 do > + if counter_0 > 5 then break end > + counter_0 = counter_0 + 1 > + > + for _ = always_number(false), 1, always_number(Name0) do > + if counter_1 > 5 then break end > + counter_1 = counter_1 + 1 > + > + repeat > + if counter_2 > 5 then break end > + counter_2 = counter_2 + 1 > + > + Name0 = Name0 + Name0 + Name0 > + Name0 = add(Name0, nil) + Name0 > + until nil > + end > +end > + > +test:ok(true, 'no stack-buffer-overflow during narrowing') > + > +test:done(true) --------------EgLPmvTMHvnKG7pz6PoIU0vH Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit

Hi, Sergey,

thanks for tha patch! LGTM with a minor comment below.

On 26.08.2024 15:37, Sergey Kaplun wrote:
From: Mike Pall <mike>

Thanks to Sergey Kaplun.

(cherry picked from commit e45fd4cb713b610506213692f3b55a1869febb03)

`narrow_conv_backprop()` misses the stack pointer (`nc->sp`) limit check
after a bunch of recursive calls that may change its value. As a result,
it leads to stack-buffer-overflow during the instruction narrowing. This
patch adds a missing check.

Sergey Kaplun:
* added the description and the test for the problem

Part of tarantool/tarantool#10199
---

Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1262-fix-limit-narrow-conv-backprop
Related issues:
* https://github.com/tarantool/tarantool/issues/10199
* https://github.com/LuaJIT/LuaJIT/issues/1262

 src/lj_opt_narrow.c                           |  3 +-
 ...62-fix-limit-narrow-conv-backprop.test.lua | 61 +++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua

diff --git a/src/lj_opt_narrow.c b/src/lj_opt_narrow.c
index db0da10f..6b6f20d3 100644
--- a/src/lj_opt_narrow.c
+++ b/src/lj_opt_narrow.c
@@ -341,7 +341,8 @@ static int narrow_conv_backprop(NarrowConv *nc, IRRef ref, int depth)
       NarrowIns *savesp = nc->sp;
       int count = narrow_conv_backprop(nc, ir->op1, depth);
       count += narrow_conv_backprop(nc, ir->op2, depth);
-      if (count <= 1) {  /* Limit total number of conversions. */
+      /* Limit total number of conversions. */
+      if (count <= 1 && nc->sp < nc->maxsp) {
 	*nc->sp++ = NARROWINS(IRT(ir->o, nc->t), ref);
 	return count;
       }
diff --git a/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua b/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua
new file mode 100644
index 00000000..6bb4025d
--- /dev/null
+++ b/test/tarantool-tests/lj-1262-fix-limit-narrow-conv-backprop.test.lua
@@ -0,0 +1,61 @@
+local tap = require('tap')
+
+-- Test file to demonstrate stack-buffer-overflow during the
+-- narrowing optimization.
+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1262.
+
+local test = tap.test('lj-1262-fix-limit-narrow-conv-backprop'):skipcond({
+  ['Test requires JIT enabled'] = not jit.status(),
+})
+
+test:plan(1)
+
+-- XXX: Test fails only under ASAN.
+-- XXX: The original reproducer was found by fuzzer:
+-- https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=70779.
+-- It creates a long side trace with a huge amount of ADD IRs,
+-- which are recursively used in the `narrow_conv_backprop()` many
+-- enough times to catch the stack-buffer-overflow. I can't
+-- simplify the reproducer any more (or write it from scratch), so
+-- I leave it in that state.
+

I would remove a sentence "I can't simplify the reproducer ..."

from the test, because it is useful information on review and

I think it is useless for those who will use the test.

Feel free to ignore and leave as is.


s/any more/anymore/
+local DEFAULT_NUMBER = 1
+local tonumber = tonumber
+
+local always_number = function(val)
+  return tonumber(val) or DEFAULT_NUMBER
+end
+
+local add = function(v1, v2)
+  return always_number(v1) + always_number(v2)
+end
+
+jit.opt.start('hotloop=1', 'hotexit=1')
+
+local counter_0 = 0
+local counter_1 = 0
+local counter_2 = 0
+local tmp = add(nil, 'Name')
+local Name0 = add(tmp, 'Name')
+-- Start a long side trace here.
+for _ = 0, 0, 0 do
+  if counter_0 > 5 then break end
+  counter_0 = counter_0 + 1
+
+  for _ = always_number(false), 1, always_number(Name0) do
+    if counter_1 > 5 then break end
+    counter_1 = counter_1 + 1
+
+    repeat
+      if counter_2 > 5 then break end
+      counter_2 = counter_2 + 1
+
+      Name0 = Name0 + Name0 + Name0
+      Name0 = add(Name0, nil) + Name0
+    until nil
+  end
+end
+
+test:ok(true, 'no stack-buffer-overflow during narrowing')
+
+test:done(true)
--------------EgLPmvTMHvnKG7pz6PoIU0vH--