From f97865fab436fba24b46dad14435ec4b482243a2 Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Thu, 8 Aug 2024 16:05:48 +0200 Subject: [PATCH] src: remove uv__node_patch_is_using_io_uring As now the `SQPOLL` ring used in the libuv io_uring implementation is disabled by default. Also modify `UvMightBeUsingIoUring()` to just handle the case where `Node.js` is dynamically linked to a `libuv` version which has the `SQPOLL` ring enabled. PR-URL: https://github.com/nodejs/node/pull/55114 Refs: https://github.com/libuv/libuv/releases/tag/v1.49.0 Refs: https://github.com/libuv/libuv/releases/tag/v1.49.1 Reviewed-By: Rafael Gonzaga Reviewed-By: Luigi Pinca --- src/node_credentials.cc | 28 +++--------- test/parallel/test-process-setuid-io-uring.js | 43 ------------------- 2 files changed, 5 insertions(+), 66 deletions(-) delete mode 100644 test/parallel/test-process-setuid-io-uring.js diff --git a/src/node_credentials.cc b/src/node_credentials.cc index 65fdd145167139..2a7f2e878bc953 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -228,31 +228,13 @@ static gid_t gid_by_name(Isolate* isolate, Local value) { } } -#ifdef __linux__ -extern "C" { -int uv__node_patch_is_using_io_uring(void); - -int uv__node_patch_is_using_io_uring(void) __attribute__((weak)); - -typedef int (*is_using_io_uring_fn)(void); -} -#endif // __linux__ - static bool UvMightBeUsingIoUring() { #ifdef __linux__ - // Support for io_uring is only included in libuv 1.45.0 and later, and only - // on Linux (and Android, but there it is always disabled). The patch that we - // apply to libuv to work around the io_uring security issue adds a function - // that tells us whether io_uring is being used. If that function is not - // present, we assume that we are dynamically linking against an unpatched - // version. - static std::atomic check = - uv__node_patch_is_using_io_uring; - if (check == nullptr) { - check = reinterpret_cast( - dlsym(RTLD_DEFAULT, "uv__node_patch_is_using_io_uring")); - } - return uv_version() >= 0x012d00u && (check == nullptr || (*check)()); + // Support for io_uring is only included in libuv 1.45.0 and later. Starting + // with 1.49.0 is disabled by default. Check the version in case Node.js is + // dynamically to an io_uring-enabled version of libuv. + unsigned int version = uv_version(); + return version >= 0x012d00u && version < 0x013100u; #else return false; #endif diff --git a/test/parallel/test-process-setuid-io-uring.js b/test/parallel/test-process-setuid-io-uring.js deleted file mode 100644 index 93193ac2f8ab99..00000000000000 --- a/test/parallel/test-process-setuid-io-uring.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; -const common = require('../common'); - -const assert = require('node:assert'); -const { execFileSync } = require('node:child_process'); - -if (!common.isLinux) { - common.skip('test is Linux specific'); -} - -if (process.arch !== 'x64' && process.arch !== 'arm64') { - common.skip('io_uring support on this architecture is uncertain'); -} - -const kv = /^(\d+)\.(\d+)\.(\d+)/.exec(execFileSync('uname', ['-r'])).slice(1).map((n) => parseInt(n, 10)); -if (((kv[0] << 16) | (kv[1] << 8) | kv[2]) < 0x050ABA) { - common.skip('io_uring is likely buggy due to old kernel'); -} - -const userIdentitySetters = [ - ['setuid', [1000]], - ['seteuid', [1000]], - ['setgid', [1000]], - ['setegid', [1000]], - ['setgroups', [[1000]]], - ['initgroups', ['nodeuser', 1000]], -]; - -for (const [fnName, args] of userIdentitySetters) { - const call = `process.${fnName}(${args.map((a) => JSON.stringify(a)).join(', ')})`; - const code = `try { ${call}; } catch (err) { console.log(err); }`; - - const stdout = execFileSync(process.execPath, ['-e', code], { - encoding: 'utf8', - env: { ...process.env, UV_USE_IO_URING: '1' }, - }); - - const msg = new RegExp(`^Error: ${fnName}\\(\\) disabled: io_uring may be enabled\\. See CVE-[X0-9]{4}-`); - assert.match(stdout, msg); - assert.match(stdout, /code: 'ERR_INVALID_STATE'/); - - console.log(call, stdout.slice(0, stdout.indexOf('\n'))); -}