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 80E6D70358; Wed, 15 Sep 2021 18:31:52 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 80E6D70358 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1631719912; bh=c8dBoY6NmVplhSmkCfYktptx81BAfx0dd0cXSF+3ZDg=; h=In-Reply-To:Date:References:To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=jz7Lbmf1lZwPGwEnJvG2B2UDBI9hv2b2raEzpQxiPHLITRzGOdI7zTkoyf86YWs4a L88ZhsT+RI1P1It62fDdSmudnMMq3e2d5pm/Vcm84ANALiA6lo8CbsmCXPjOVChcYI a0fOYVeXB2yawT3/GiIyFrmH6+tRf7w2jbJMkHiI= Received: from smtp50.i.mail.ru (smtp50.i.mail.ru [94.100.177.110]) (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 9FDA870CA8 for ; Wed, 15 Sep 2021 18:31:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 9FDA870CA8 Received: by smtp50.i.mail.ru with esmtpa (envelope-from ) id 1mQWsS-0005Tc-O0; Wed, 15 Sep 2021 18:31:13 +0300 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.13\)) In-Reply-To: <45fce284fce8df636a18e7303114f82d5bbce2f0.1631170629.git.skaplun@tarantool.org> Date: Wed, 15 Sep 2021 18:31:12 +0300 Content-Transfer-Encoding: quoted-printable Message-Id: <31B92E03-B5C4-4719-9191-41D8581C930E@tarantool.org> References: <45fce284fce8df636a18e7303114f82d5bbce2f0.1631170629.git.skaplun@tarantool.org> To: Sergey Kaplun X-Mailer: Apple Mail (2.3654.120.0.1.13) X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD91AE02D33A9C88A2FF3F790D2CFB1565D68082CE688654CB400894C459B0CD1B9315DD324FDEBBC3D0A8F9700A1452764CF4949AA5CD683920422B37ABB051B9D X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7370F4F695FFFC24BEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006375104F503C4FA42DF8638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8658E4A46C74037336E7B038CE02484B5117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCF1175FABE1C0F9B6A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352033AC447995A7AD182CC0D3CB04F14752D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6BDB3AEF73D8456A4089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A213B5FB47DCBC3458834459D11680B5057B9F0947652975103101C983B23679DA X-C1DE0DAB: 0D63561A33F958A5C73082C81BE44755C74A6ED13383130D4E4EA0E13767B72AD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA7502E6951B79FF9A3F410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D349320586B19AD2C72107ADEA9E6754060374944EF031E45C6F7680D4FEFC6B6AA92B52C440D8BD18B1D7E09C32AA3244CE8C33C6098B8C3BFA3AD2585BDA3BDC5B038C9161EF167A1FACE5A9C96DEB163 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojmwY/hTp72s9wIMJILsRTNg== X-Mailru-Sender: 3B9A0136629DC912F4AABCEFC589C81E74844DF9CD1EF62D7FD7466956672DAFD97C9CCDEB355310AD07DD1419AC565FA614486B47F28B67C5E079CCF3B0523AED31B7EB2E253A9E112434F685709FCF0DA7A0AF5A3A8387 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 3/3] Avoid conflict between 64 bit lightuserdata and ITERN key. 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: sergos via Tarantool-patches Reply-To: sergos Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Hi! Thanks for the patch! Just some test comment. Regards, Sergos > On 9 Sep 2021, at 10:03, Sergey Kaplun wrote: >=20 > From: Mike Pall >=20 > Reported by XmiliaH. >=20 > (cherry picked from commit 16d38a4b214e8b8a20be554be77bd20286072365) >=20 > This patch fixes the regression introduced in scope of > fa8e7ffefb715abf55dc5b0c708c63251868 ('Add support for full-range > 64 bit lightuserdata.'). >=20 > The maximum available number of lightuserdata segment is 255. So the > high bits of this lightuserdata TValue are 0xfffe7fff. The same high > bits are set for special control variable on the stack for ITERN/ITERC > bytecodes via ISNEXT bytecode. When ITERN bytecode is despecialize to > ITERC bytecode and a table has the lightuserdata with the maximum > available segment number as a key, the special control variable is > considered as this key and iteration is broken. >=20 > This patch forbids to use more than 254 lightuserdata segments to > avoid clashing with the aforementioned control variable. In case when > user tries to create lightuserdata with 255th segment number an error > "bad light userdata pointer" is raised. >=20 > Sergey Kaplun: > * added the description and the test for the problem >=20 > Part of tarantool/tarantool#5629 > --- > src/lj_udata.c | 3 +- > test/tarantool-tests/CMakeLists.txt | 1 + > .../lj-727-lightuserdata-itern.test.lua | 48 ++++++++++++++ > .../lj-727-lightuserdata-itern/CMakeLists.txt | 1 + > .../lightuserdata.c | 63 +++++++++++++++++++ > 5 files changed, 115 insertions(+), 1 deletion(-) > create mode 100644 = test/tarantool-tests/lj-727-lightuserdata-itern.test.lua > create mode 100644 = test/tarantool-tests/lj-727-lightuserdata-itern/CMakeLists.txt > create mode 100644 = test/tarantool-tests/lj-727-lightuserdata-itern/lightuserdata.c >=20 > diff --git a/src/lj_udata.c b/src/lj_udata.c > index 6808b1bc..1b7841fa 100644 > --- a/src/lj_udata.c > +++ b/src/lj_udata.c > @@ -49,9 +49,10 @@ void *lj_lightud_intern(lua_State *L, void *p) > if (segmap[seg] =3D=3D up) /* Fast path. */ > return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | = lightudlo(u)); > segnum++; > + /* Leave last segment unused to avoid clash with ITERN key. */ > + if (segnum >=3D (1 << LJ_LIGHTUD_BITS_SEG)-1) lj_err_msg(L, = LJ_ERR_BADLU); > } > if (!((segnum-1) & segnum) && segnum !=3D 1) { > - if (segnum >=3D (1 << LJ_LIGHTUD_BITS_SEG)) lj_err_msg(L, = LJ_ERR_BADLU); > lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, = uint32_t); > setmref(g->gc.lightudseg, segmap); > } > diff --git a/test/tarantool-tests/CMakeLists.txt = b/test/tarantool-tests/CMakeLists.txt > index a872fa5e..c933cc3f 100644 > --- a/test/tarantool-tests/CMakeLists.txt > +++ b/test/tarantool-tests/CMakeLists.txt > @@ -60,6 +60,7 @@ add_subdirectory(gh-4427-ffi-sandwich) > add_subdirectory(gh-6098-fix-side-exit-patching-on-arm64) > add_subdirectory(gh-6189-cur_L) > add_subdirectory(lj-49-bad-lightuserdata) > +add_subdirectory(lj-727-lightuserdata-itern) > add_subdirectory(lj-flush-on-trace) > add_subdirectory(misclib-getmetrics-capi) >=20 > diff --git a/test/tarantool-tests/lj-727-lightuserdata-itern.test.lua = b/test/tarantool-tests/lj-727-lightuserdata-itern.test.lua > new file mode 100644 > index 00000000..ebe885bf > --- /dev/null > +++ b/test/tarantool-tests/lj-727-lightuserdata-itern.test.lua > @@ -0,0 +1,48 @@ > +local tap =3D require('tap') > + > +-- Test file to demonstrate next FF incorrect behaviour on LJ_64. > +-- See also, https://github.com/LuaJIT/LuaJIT/issues/727. > + > +local test =3D tap.test('lj-727-lightuserdata-itern') > +test:plan(1) > + > +local ud =3D require('lightuserdata').craft_ptr_wp() > + > +-- We now have the tagged lightuuserdata pointer > +-- 0xFFFE7FFF00000002 in the up before this patch (after the patch > +-- the maximum available lightuserdata segment is 0xffe). Shall we end the test here with just an expectation of an error? I believe you can make a way simpler test: pcall(craft_ptr()) should = work successfully 254 times and error on an 255th one, isn=E2=80=99t it? > + > +-- These pointers are special in for loop keys as they are used in > +-- the INTERN control variable to denote the current index in the > +-- array. > +-- If the ITERN is then patched to ITERC because of > +-- despecialization via the ISNEXT bytecode, the control variable > +-- is considered as the existing key in the table and some > +-- elements are skipped during iteration. > + > +local real_next =3D next > +local next =3D next > + > +local function itern_test(t, f) > + for k, v in next, t do > + f(k, v) > + end > +end > + > +local visited =3D {} > +local t =3D {1, [ud] =3D 2345} > +itern_test(t, function(k, v) > + visited[k] =3D v > + if next =3D=3D real_next then > + next =3D function(tab, key) > + return real_next(tab, key) > + end > + -- Despecialize bytecode. > + itern_test({}, function() end) > + end > +end) > + > +test.strict =3D true > +test:is_deeply(visited, t, 'userdata node is visited') > + > +os.exit(test:check() and 0 or 1) > diff --git = a/test/tarantool-tests/lj-727-lightuserdata-itern/CMakeLists.txt = b/test/tarantool-tests/lj-727-lightuserdata-itern/CMakeLists.txt > new file mode 100644 > index 00000000..564b688b > --- /dev/null > +++ b/test/tarantool-tests/lj-727-lightuserdata-itern/CMakeLists.txt > @@ -0,0 +1 @@ > +BuildTestCLib(lightuserdata lightuserdata.c) > diff --git = a/test/tarantool-tests/lj-727-lightuserdata-itern/lightuserdata.c = b/test/tarantool-tests/lj-727-lightuserdata-itern/lightuserdata.c > new file mode 100644 > index 00000000..0fe6441c > --- /dev/null > +++ b/test/tarantool-tests/lj-727-lightuserdata-itern/lightuserdata.c > @@ -0,0 +1,63 @@ > +#include > +#include > + > +#undef NDEBUG > +#include > + > +/* To stay within 47 bits, lightuserdata is segmented. */ > +#define LJ_LIGHTUD_BITS_SEG 8 > +#define NSEGMENTS ((1 << LJ_LIGHTUD_BITS_SEG)-1) > + > +/* > + * The function to wrap: get a number to form lightuserdata to > + * return with the 0xXXXXXfff00000002 format. > + * It may raise an error, when the available lightuserdata > + * segments are run out. > + */ > +static int craft_ptr(lua_State *L) > +{ > + const unsigned long long i =3D lua_tonumber(L, 1); > + lua_pushlightuserdata(L, (void *)((i << 44) + 0xfff00000002)); > + return 1; > +} > + > +/* > + * The function to generate bunch of lightuserdata of the > + * 0xXXXXXfff00000002 format and push the last one on the stack. > + */ > +static int craft_ptr_wp(lua_State *L) > +{ > + void *ptr =3D NULL; > + /* > + * There are only 255 available lightuserdata segments. > + * Generate a bunch of pointers to take them all. > + * XXX: After this patch the last userdata segment is > + * reserved for ISNEXT/ITERC/ITERN control variable, so > + * `craft_ptr()` function will raise an error at the last > + * iteration. > + */ > + unsigned long long i =3D 0; > + for (; i < NSEGMENTS; i++) { > + lua_pushcfunction(L, craft_ptr); > + lua_pushnumber(L, i); > + if (lua_pcall(L, 1, 1, 0) =3D=3D LUA_OK) > + ptr =3D (void *)lua_topointer(L, -1); > + else > + break; > + } > + assert(ptr !=3D NULL); > + /* Overwrite possible error message. */ > + lua_pushlightuserdata(L, ptr); > + return 1; > +} > + > +static const struct luaL_Reg lightuserdata[] =3D { > + {"craft_ptr_wp", craft_ptr_wp}, > + {NULL, NULL} > +}; > + > +LUA_API int luaopen_lightuserdata(lua_State *L) > +{ > + luaL_register(L, "lightuserdata", lightuserdata); > + return 1; > +} > --=20 > 2.31.0 >=20