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 5232F6ECCD; Tue, 28 Jul 2026 10:37:38 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 5232F6ECCD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1785224258; bh=T4jD59Pds1kX5hsNy/bqbUjdKojgpzu2u2sEhf1cCy4=; 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=PWZbeDrQ6pgTZlYoWxmjIf3gNrH2WJ4po2RUhsiWdBjbUUG77JEhDkE/Uxdr+6eF5 mPKGKoTH7KKdHr5bGcbFHxzwYvUS+EgQg1O2Fa6eIdvrV0kBLJWA5HNl4bkW1mol5Z oMFaVChUrE58h3HLw1Ci1KfVXTYO2Z8RbMP+DAJw= Received: from send217.i.mail.ru (send217.i.mail.ru [95.163.59.56]) (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 E613A6ECCD for ; Tue, 28 Jul 2026 10:37:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E613A6ECCD Received: by exim-smtp-6c76488b9f-d7k6v with esmtpa (envelope-from ) id 1wocNb-000000000UI-3W75; Tue, 28 Jul 2026 10:37:36 +0300 Content-Type: multipart/alternative; boundary="------------G24ywDuR5iD8sYmx5vKPXm3H" Message-ID: <844144db-0e6e-4296-9cdf-97ffde887d44@tarantool.org> Date: Tue, 28 Jul 2026 10:37:34 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Sergey Bronnikov Cc: tarantool-patches@dev.tarantool.org References: <7266d024dc58e71ec74929a2f2973c4454161c59.1784895433.git.sergeyb@tarantool.org> In-Reply-To: X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD93AE80F4FE6181E4F51F6E9D49FC1F292CD1DBDA51D725763182A05F5380850405C3038ACABD807A53DE06ABAFEAF6705D4226173FB5CCDC8101AED2C22CD3EFCCFC0F0949690F79B X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7C4FDA87F74E4A9F6EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB553375666E0AFCC7CBCEC7C781FEA0124B9CACF3DDC23AD119E6EC321D8EE7DE0D1B836E389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C0DCF4F0DC832992758941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B6A50BD5087FBFCDAACC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB8D32BA5DBAC0009BE9E8FC8737B5C22494705F91287EA2BDB76E601842F6C81A12EF20D2F80756B5FB606B96278B59C4276E601842F6C81A127C277FBC8AE2E8BA1EEF9386886340E3AA81AA40904B5D99C9F4D5AE37F343AD1F44FA8B9022EA23BBE47FD9DD3FB595F5C1EE8F4F765FC72CEEB2601E22B093A03B725D353964B0B7D0EA88DDEDAC722CA9DD8327EE4930A3850AC1BE2E735F3CCD8A865B74A75C4224003CC83647689D4C264860C145E X-C1DE0DAB: 0D63561A33F958A5248E417671F421AF5002B1117B3ED696BE0CDE21689E8849FB820E9FE7BD014C823CB91A9FED034534781492E4B8EEAD37F46C620FF2CAEEBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE1918E10F71CB4DF9F96AB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D659CCDC820B8796B1F837E10DD248D011C7C3B0FAD426F549C762268ADD282F0878D0E12360963B7E79B8341EE9D5BE9A0A55968FDB01DA10807A135972C3D19743B3CA1FC93178E6516536EB022892E5344C41F94D744909CE2512F26BEC029E55448553D2254B8D95CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVczkDsfooUjfy7Pzs+W5u6U= X-Mailru-Sender: C4F68CFF4024C8867DFDF7C7F25884586F971033A7CCEC1797B151A33FA7A9F83090435026A1FFFE97C07B33C6D957A5645D15D82EE4B272BD6E4642A116CA93524AA66B5ACBE6721EF430B9A63E2A504198E0F3ECE9B5443453F38A29522196 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit] FFI: Prevent sanitizer warning in carith_ptr(). 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. --------------G24ywDuR5iD8sYmx5vKPXm3H Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello, Thanks for review! See my comments. Fixes are applied and the branch was force-pushed. Sergey On 7/27/26 10:39, Sergey Kaplun via Tarantool-patches wrote: > Hi, Sergey! > Thanks for the patch! > Please consider my comments below. > > On 24.07.26, Sergey Bronnikov wrote: >> From: Mike Pall >> >> Reported by Sergey Bronnikov. >> >> (cherry picked from commit c3b379bf50c8819c61daa3afd9f21d9ec5708bd5) >> > Side note: We may mention that this is a follow-up for the commit > 78f4de4d7d0c410eeaf75cec5bb178fdb7db1452 ("Avoid negation of signed > integers in C that may hold INT*_MIN."). Updated, updated commit message is below:     FFI: Prevent sanitizer warning in carith_ptr().     Reported by Sergey Bronnikov.     (cherry picked from commit c3b379bf50c8819c61daa3afd9f21d9ec5708bd5)     The Undefined Behaviour Sanitizer [1] produce a warning about     signed integer overflow in the function carith_ptr(), when idx     equals INT_MIN in the expression idx = -idx. In practice,     negating -2147483648 wraps back to itself instead of producing the     correct positive value, leading to incorrect pointer arithmetic in     carith_ptr() for MM_sub (pointer subtraction). The patch fixes     that by converting idx to unsigned (uintptr_t), computes two's     complement negation via bitwise negation + 1 (safe from overflow     in unsigned arithmetic), and casts back to ptrdiff_t. This avoids     signed overflow entirely and correctly negates even the INT_MIN     edge case.     The patch follows up the commit 78f4de4d7d0c410eeaf75cec5bb178fdb7db1452     ("Avoid negation of signed integers in C that may hold INT*_MIN.").     [1]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html     Sergey Bronnikov:     * added the description and the test for the problem     Part of tarantool/tarantool#12480 > > Feel free to ignore. > >> The Undefined Behaviour Sanitizer [1] produce a warning about > Typo: s/produce/produces/ Fixed, thanks. >> signed integer overflow in the function carith_ptr(), when idx >> equals INT_MIN in the expression idx = -idx. In practice, >> negating -2147483648 wraps back to itself instead of producing the > It's actually -9223372036854775808 or -0x8000000000000000 for 64-bit > architecture. Let's use hexademic notation (or just the `INT_MIN`) > instead of this number. replaced the number with INT_MIN > >> correct positive value, leading to incorrect pointer arithmetic in >> carith_ptr() for MM_sub (pointer subtraction). The patch fixes >> that by converting idx to unsigned (uintptr_t), computes two's >> complement negation via bitwise negation + 1 (safe from overflow >> in unsigned arithmetic), and casts back to ptrdiff_t. This avoids >> signed overflow entirely and correctly negates even the INT_MIN >> edge case. >> >> [1]:https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html >> >> Sergey Bronnikov: >> * added the description and the test for the problem >> >> Part of tarantool/tarantool#12480 > Typo: s/12480/12880/ Fixed, thanks! > >> --- >> >> Branch:https://github.com/tarantool/luajit/tree/ligurio/lj-1459-ub-carith_ptr >> Related issues: >> -https://github.com/LuaJIT/LuaJIT/issues/1459 >> -https://github.com/tarantool/tarantool/issues/12880 >> >> src/lj_carith.c | 2 +- >> .../lj-1459-subtraction-carith.test.lua | 16 ++++++++++++++++ >> 2 files changed, 17 insertions(+), 1 deletion(-) >> create mode 100644 test/tarantool-tests/lj-1459-subtraction-carith.test.lua >> >> diff --git a/src/lj_carith.c b/src/lj_carith.c >> index eb56d552..e971bfc2 100644 >> --- a/src/lj_carith.c >> +++ b/src/lj_carith.c > > >> diff --git a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua >> new file mode 100644 >> index 00000000..df401a56 >> --- /dev/null >> +++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua >> @@ -0,0 +1,16 @@ >> +local tap = require('tap') >> + >> +-- The test file to demonstrate UBSan warning in carith_ptr(). > Typo: s/UBSan/the UBSan/ > Minor: s/carith_ptr()/`carith_ptr()`/ Updated: --- a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua +++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua @@ -1,6 +1,7 @@  local tap = require('tap') --- The test file to demonstrate UBSan warning in carith_ptr(). +-- The test file to demonstrate the UBSan warning in +-- `carith_ptr()`.  -- See also: https://github.com/LuaJIT/LuaJIT/issues/1459.  local test = tap.test('lj-1459-subtraction-carith') > >> +-- See also:https://github.com/LuaJIT/LuaJIT/issues/1459. >> +local test = tap.test('lj-1459-subtraction-carith') >> + >> +test:plan(2) >> + >> +local func = load('_ = nil - 0LL%0') > Minor: Let's use loadstring instead (I know that they are literally the > same function in LuaJIT, but it's semantically better to use it for > loading strings, while `load()` is used for generators). > > For Lua 5.1 they are not the same: > > | lua5.1 -e 'load"print(1)"()' > | lua5.1: (command line):1: bad argument #1 to 'load' (function expected, got string) > > The `loadstring()` has been deprecated in Lua5.2. > > > This `0LL%0` looks weird. Let's just use the resulting > `-0x8000000000000000LL` instead. > > > Also, please add the comment that `nil` as the first operand of > subtraction is required, since it is required to trigger metamethod > invocation. It successfully passes the argument check since it may be > considered as NULL ptr for other metamethods. Updated: --- a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua +++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua @@ -7,7 +7,11 @@ local test = tap.test('lj-1459-subtraction-carith') test:plan(2) -local func = loadstring('_ = nil - 0LL%0') +-- The `nil` as the first operand of subtraction is required, +-- since it is required to trigger metamethod invocation. +-- It successfully passes the argument check since it may be +-- considered as NULL ptr for other metamethods. +local func = loadstring('_ = nil - 0x8000000000000000LL')  local res, err = pcall(func) test:is(res, false, 'correct result') > >> +local res, err = pcall(func) >> + >> +test:is(res, false, 'correct result') >> +local error_msg = "attempt to perform arithmetic on 'nil' and 'int64_t'" >> +test:ok(err:match(error_msg), 'error on subtraction') >> + >> +test:done(true) >> -- >> 2.43.0 >> --------------G24ywDuR5iD8sYmx5vKPXm3H Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hello,

Thanks for review! See my comments.

Fixes are applied and the branch was force-pushed.

Sergey

On 7/27/26 10:39, Sergey Kaplun via Tarantool-patches wrote:
Hi, Sergey!
Thanks for the patch!
Please consider my comments below.

On 24.07.26, Sergey Bronnikov wrote:
From: Mike Pall <mike>

Reported by Sergey Bronnikov.

(cherry picked from commit c3b379bf50c8819c61daa3afd9f21d9ec5708bd5)

Side note: We may mention that this is a follow-up for the commit
78f4de4d7d0c410eeaf75cec5bb178fdb7db1452 ("Avoid negation of signed
integers in C that may hold INT*_MIN.").

Updated, updated commit message is below:

    FFI: Prevent sanitizer warning in carith_ptr().
    
    Reported by Sergey Bronnikov.
    
    (cherry picked from commit c3b379bf50c8819c61daa3afd9f21d9ec5708bd5)
    
    The Undefined Behaviour Sanitizer [1] produce a warning about
    signed integer overflow in the function carith_ptr(), when idx
    equals INT_MIN in the expression idx = -idx. In practice,
    negating -2147483648 wraps back to itself instead of producing the
    correct positive value, leading to incorrect pointer arithmetic in
    carith_ptr() for MM_sub (pointer subtraction). The patch fixes
    that by converting idx to unsigned (uintptr_t), computes two's
    complement negation via bitwise negation + 1 (safe from overflow
    in unsigned arithmetic), and casts back to ptrdiff_t. This avoids
    signed overflow entirely and correctly negates even the INT_MIN
    edge case.
    
    The patch follows up the commit 78f4de4d7d0c410eeaf75cec5bb178fdb7db1452
    ("Avoid negation of signed integers in C that may hold INT*_MIN.").
    
    [1]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
    
    Sergey Bronnikov:
    * added the description and the test for the problem
    
    Part of tarantool/tarantool#12480



Feel free to ignore.

The Undefined Behaviour Sanitizer [1] produce a warning about
Typo: s/produce/produces/

Fixed, thanks.


      
signed integer overflow in the function carith_ptr(), when idx
equals INT_MIN in the expression idx = -idx. In practice,
negating -2147483648 wraps back to itself instead of producing the
It's actually -9223372036854775808 or -0x8000000000000000 for 64-bit
architecture. Let's use hexademic notation (or just the `INT_MIN`)
instead of this number.
replaced the number with INT_MIN

correct positive value, leading to incorrect pointer arithmetic in
carith_ptr() for MM_sub (pointer subtraction). The patch fixes
that by converting idx to unsigned (uintptr_t), computes two's
complement negation via bitwise negation + 1 (safe from overflow
in unsigned arithmetic), and casts back to ptrdiff_t. This avoids
signed overflow entirely and correctly negates even the INT_MIN
edge case.

[1]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

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

Part of tarantool/tarantool#12480
Typo: s/12480/12880/
Fixed, thanks!

---

Branch: https://github.com/tarantool/luajit/tree/ligurio/lj-1459-ub-carith_ptr
Related issues:
- https://github.com/LuaJIT/LuaJIT/issues/1459
- https://github.com/tarantool/tarantool/issues/12880

 src/lj_carith.c                                  |  2 +-
 .../lj-1459-subtraction-carith.test.lua          | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 test/tarantool-tests/lj-1459-subtraction-carith.test.lua

diff --git a/src/lj_carith.c b/src/lj_carith.c
index eb56d552..e971bfc2 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
<snipped>

diff --git a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
new file mode 100644
index 00000000..df401a56
--- /dev/null
+++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
@@ -0,0 +1,16 @@
+local tap = require('tap')
+
+-- The test file to demonstrate UBSan warning in carith_ptr().
Typo: s/UBSan/the UBSan/
Minor: s/carith_ptr()/`carith_ptr()`/

Updated:

--- a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
+++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
@@ -1,6 +1,7 @@
 local tap = require('tap')
 
--- The test file to demonstrate UBSan warning in carith_ptr().
+-- The test file to demonstrate the UBSan warning in
+-- `carith_ptr()`.
 -- See also: https://github.com/LuaJIT/LuaJIT/issues/1459.
 local test = tap.test('lj-1459-subtraction-carith')
 


+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1459.
+local test = tap.test('lj-1459-subtraction-carith')
+
+test:plan(2)
+
+local func = load('_ = nil - 0LL%0')
Minor: Let's use loadstring instead (I know that they are literally the
same function in LuaJIT, but it's semantically better to use it for
loading strings, while `load()` is used for generators).

For Lua 5.1 they are not the same:

| lua5.1 -e 'load"print(1)"()'
| lua5.1: (command line):1: bad argument #1 to 'load' (function expected, got string)

The `loadstring()` has been deprecated in Lua5.2.


This `0LL%0` looks weird. Let's just use the resulting
`-0x8000000000000000LL` instead.


Also, please add the comment that `nil` as the first operand of
subtraction is required, since it is required to trigger metamethod
invocation. It successfully passes the argument check since it may be
considered as NULL ptr for other metamethods.

Updated:

--- a/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
+++ b/test/tarantool-tests/lj-1459-subtraction-carith.test.lua
@@ -7,7 +7,11 @@ local test = tap.test('lj-1459-subtraction-carith')
 
 test:plan(2)
 
-local func = loadstring('_ = nil - 0LL%0')
+-- The `nil` as the first operand of subtraction is required,
+-- since it is required to trigger metamethod invocation.
+-- It successfully passes the argument check since it may be
+-- considered as NULL ptr for other metamethods.
+local func = loadstring('_ = nil - 0x8000000000000000LL')
 local res, err = pcall(func)
 
 test:is(res, false, 'correct result')


+local res, err = pcall(func)
+
+test:is(res, false, 'correct result')
+local error_msg = "attempt to perform arithmetic on 'nil' and 'int64_t'"
+test:ok(err:match(error_msg), 'error on subtraction')
+
+test:done(true)
-- 
2.43.0


    
--------------G24ywDuR5iD8sYmx5vKPXm3H--