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 3A219CE855E; Fri, 13 Sep 2024 11:06:04 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 3A219CE855E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1726214764; bh=ck/g/3VUJAbHNDnkllnSlm25wv3sVnzWW+TzPLoeULo=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=MaHSiESu1idxh+SLtYdBcfiNA04+V2rTcYTRPhpIodM9ntqfjTGJ2IMiUuOPWTBxm RBu7mic9UW/F0UKPRLudIPa+p3Ahbts2HiiSk43PeV/5Z8QPSQASd3zXD+fniEQJWP 5tWifvK0Cnt+W8pStkgETP4RxBYHQTbVRSUH4uQY= Received: from smtp37.i.mail.ru (smtp37.i.mail.ru [95.163.41.78]) (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 02774CE8567 for ; Fri, 13 Sep 2024 11:06:03 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 02774CE8567 Received: by smtp37.i.mail.ru with esmtpa (envelope-from ) id 1sp1JZ-0000000DSxC-0K36; Fri, 13 Sep 2024 11:06:01 +0300 To: Maxim Kokryashkin , Sergey Bronnikov Date: Fri, 13 Sep 2024 11:05:50 +0300 Message-ID: <20240913080550.22599-1-skaplun@tarantool.org> X-Mailer: git-send-email 2.46.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Mailru-Src: smtp X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD91486559A3ABF84E7F65EB02EE40C4147DEE5F54498FF1C3C182A05F538085040EE5D850287F78682AC8EDD30083ED68E355A95400E6B5D72C76BD08BD9859AAC75832A37A19CB0B4 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7FEAC828D2BF6EC3CEA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063750DEB490C003C9A78638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D81151B73EAC43E3096BB152E2D1A8D0F27EA45B5FABEF0C38CC7F00164DA146DAFE8445B8C89999728AA50765F7900637F924B32C592EA89F389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC8A9FF340AA05FB58CF6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA7E827F84554CEF5019E625A9149C048EE9ECD01F8117BC8BEE2021AF6380DFAD18AA50765F790063735872C767BF85DA227C277FBC8AE2E8B53A69B3AC30C7B9475ECD9A6C639B01B4E70A05D1297E1BBCB5012B2E24CD356 X-C1DE0DAB: 0D63561A33F958A51E271FFF34EC255B5002B1117B3ED69697F4A1E3A6A900557E0012C66AE17B00823CB91A9FED034534781492E4B8EEAD003C2D46C52F18F2C79554A2A72441328621D336A7BC284946AD531847A6065A535571D14F44ED41 X-C8649E89: 1C3962B70DF3F0ADE00A9FD3E00BEEDF77DD89D51EBB7742D3581295AF09D3DF87807E0823442EA2ED31085941D9CD0AF7F820E7B07EA4CFC478825395B1733F2DC5FE2B2CFCC1D8DEA0C506F89011094BE9777210FC92DFCBE0296D7E8D7E7CBEF149BEF2827C685C5853DF9E459ED065A0D3BDBD1B69355BBB24A73919C41BC226CC413062362A913E6812662D5F2A5EAB5682573093F7837F15F2B5E4A70B33F2C28C22F508233FCF178C6DD14203 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojmn7hiCWKTujYr0QkRVuxiA== X-DA7885C5: 1DCC3A099033E490F255D290C0D534F9427E94B1A7072258C3A759C83DE8EFC83CAEAC6E92F8CD0E5B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393C6D0B12EA33CAA9BF86E548A78F1D9CA46D1150F557AB93197DE729A3BE0941AE49D44BB4BD9522A059A1ED8796F048DB274557F927329BE89D5A3BC2B10C37545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit] FFI: Workaround for platform dlerror() returning NULL. 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 Contributed by mcclure. (cherry picked from commit 478bcfe52a653bf338f17690147fa9f5793f5b42) The `ffi.load()` implementation assumes the string returned from `dlerror()` is non-NULL and immediately dereferences it. This may lead to a crash on some platforms like Android (Oculus Quest) where it is possible. This patch adds the corresponding check and the default "dlopen failed" error message. 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-522-fix-dlerror-return-null Related Issues: * https://github.com/LuaJIT/LuaJIT/pull/522 * https://github.com/tarantool/tarantool/issues/10199 src/lj_clib.c | 3 ++- test/tarantool-tests/CMakeLists.txt | 1 + .../lj-522-fix-dlerror-return-null.test.lua | 27 +++++++++++++++++++ .../CMakeLists.txt | 1 + .../mydlerror.c | 6 +++++ .../lj-522-fix-dlerror-return-null/script.lua | 10 +++++++ 6 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/tarantool-tests/lj-522-fix-dlerror-return-null.test.lua create mode 100644 test/tarantool-tests/lj-522-fix-dlerror-return-null/CMakeLists.txt create mode 100644 test/tarantool-tests/lj-522-fix-dlerror-return-null/mydlerror.c create mode 100644 test/tarantool-tests/lj-522-fix-dlerror-return-null/script.lua diff --git a/src/lj_clib.c b/src/lj_clib.c index 2f11b2e9..9716684c 100644 --- a/src/lj_clib.c +++ b/src/lj_clib.c @@ -119,12 +119,13 @@ static void *clib_loadlib(lua_State *L, const char *name, int global) RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL)); if (!h) { const char *e, *err = dlerror(); - if (*err == '/' && (e = strchr(err, ':')) && + if (err && *err == '/' && (e = strchr(err, ':')) && (name = clib_resolve_lds(L, strdata(lj_str_new(L, err, e-err))))) { h = dlopen(name, RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL)); if (h) return h; err = dlerror(); } + if (!err) err = "dlopen failed"; lj_err_callermsg(L, err); } return h; diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt index e3750bf3..0bd3e6fc 100644 --- a/test/tarantool-tests/CMakeLists.txt +++ b/test/tarantool-tests/CMakeLists.txt @@ -28,6 +28,7 @@ add_subdirectory(gh-5813-resolving-of-c-symbols/stripped) add_subdirectory(gh-6098-fix-side-exit-patching-on-arm64) add_subdirectory(gh-6189-cur_L) add_subdirectory(lj-416-xor-before-jcc) +add_subdirectory(lj-522-fix-dlerror-return-null) add_subdirectory(lj-549-bytecode-loader) add_subdirectory(lj-551-bytecode-c-broken-macro) add_subdirectory(lj-601-fix-gc-finderrfunc) diff --git a/test/tarantool-tests/lj-522-fix-dlerror-return-null.test.lua b/test/tarantool-tests/lj-522-fix-dlerror-return-null.test.lua new file mode 100644 index 00000000..f9f4af6a --- /dev/null +++ b/test/tarantool-tests/lj-522-fix-dlerror-return-null.test.lua @@ -0,0 +1,27 @@ +local tap = require('tap') +local test = tap.test('lj-522-fix-dlerror-return-null'):skipcond({ + -- XXX: Unfortunately, it's too hard to overload (or even + -- impossible, who knows, since Cupertino fellows do not + -- provide any information about their system) something from + -- dyld sharing cache (includes the library + -- providing `dlerror()`). + -- All in all, this test checks the part that is common for all + -- platforms, so it's not vital to run this test on macOS since + -- everything can be checked on Linux in a much easier way. + [' cannot be overridden on macOS'] = jit.os == 'OSX', +}) + +test:plan(1) + +-- `makecmd()` runs <%testname%/script.lua> by +-- `LUAJIT_TEST_BINARY` with the given environment and launch +-- options. +local script = require('utils').exec.makecmd(arg, { + env = { LD_PRELOAD = 'mydlerror.so' }, + redirect = '2>&1', +}) + +local output = script() +test:like(output, 'dlopen failed', 'correct error message') + +test:done(true) diff --git a/test/tarantool-tests/lj-522-fix-dlerror-return-null/CMakeLists.txt b/test/tarantool-tests/lj-522-fix-dlerror-return-null/CMakeLists.txt new file mode 100644 index 00000000..903da4d3 --- /dev/null +++ b/test/tarantool-tests/lj-522-fix-dlerror-return-null/CMakeLists.txt @@ -0,0 +1 @@ +BuildTestCLib(mydlerror mydlerror.c) diff --git a/test/tarantool-tests/lj-522-fix-dlerror-return-null/mydlerror.c b/test/tarantool-tests/lj-522-fix-dlerror-return-null/mydlerror.c new file mode 100644 index 00000000..89e881e4 --- /dev/null +++ b/test/tarantool-tests/lj-522-fix-dlerror-return-null/mydlerror.c @@ -0,0 +1,6 @@ +#include + +char *dlerror(void) +{ + return NULL; +} diff --git a/test/tarantool-tests/lj-522-fix-dlerror-return-null/script.lua b/test/tarantool-tests/lj-522-fix-dlerror-return-null/script.lua new file mode 100644 index 00000000..b2f673c9 --- /dev/null +++ b/test/tarantool-tests/lj-522-fix-dlerror-return-null/script.lua @@ -0,0 +1,10 @@ +local ffi = require('ffi') + +-- Overloaded `dlerror()` returns NULL after trying to load an +-- unexisting file. +local res, errmsg = pcall(ffi.load, 'lj-522-fix-dlerror-return-null-unexisted') + +assert(not res, 'pcall should fail') + +-- Return the error message to be checked by the TAP. +io.write(errmsg) -- 2.46.0