From 25b8c4361a695af98fe9dad8b3dc82e74a4caa6e Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 10 Jul 2026 16:58:22 -0700 Subject: [PATCH 1/2] Report host uid/gid credentials under NODERAWFS getuid/geteuid/getgid/getegid report the real host process credentials under NODERAWFS (via node's process.get*id()), rather than always 0. These move from weak C stubs to the JS syscall layer, since a weak C definition would otherwise win over the JS override and the syscall would keep returning 0. Other backends (and Windows, which has no uid/gid concept) continue to report 0. The set* variants remain EPERM: musl routes them through __setxid, which emscripten stubs out because it relies on dynamic (numeric) syscall dispatch. Adds NODERAWFS test coverage: test_fs_getuid_noderawfs. --- src/lib/libsigs.js | 4 ++++ src/lib/libsyscall.js | 17 ++++++++++++++ system/lib/libc/emscripten_syscall_stubs.c | 16 ------------- system/lib/wasmfs/syscalls.cpp | 7 ++++++ .../test_codesize_hello_dylink_all.json | 22 ++++++++++++------ test/fs/test_getuid_noderawfs.c | 23 +++++++++++++++++++ test/test_core.py | 7 ++++++ 7 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 test/fs/test_getuid_noderawfs.c diff --git a/src/lib/libsigs.js b/src/lib/libsigs.js index 538f80c9b7c2b..6a17a752a9e49 100644 --- a/src/lib/libsigs.js +++ b/src/lib/libsigs.js @@ -255,9 +255,13 @@ sigs = { __syscall_ftruncate64__sig: 'iij', __syscall_getcwd__sig: 'ipp', __syscall_getdents64__sig: 'iipp', + __syscall_getegid32__sig: 'i', + __syscall_geteuid32__sig: 'i', + __syscall_getgid32__sig: 'i', __syscall_getpeername__sig: 'iippiii', __syscall_getsockname__sig: 'iippiii', __syscall_getsockopt__sig: 'iiiippi', + __syscall_getuid32__sig: 'i', __syscall_ioctl__sig: 'iiip', __syscall_linkat__sig: 'iipipi', __syscall_listen__sig: 'iiiiiii', diff --git a/src/lib/libsyscall.js b/src/lib/libsyscall.js index 603fdae2a50f3..73260ff518879 100644 --- a/src/lib/libsyscall.js +++ b/src/lib/libsyscall.js @@ -1084,6 +1084,23 @@ var SyscallsLibrary = { } return 0; }, + __syscall_getuid32__nothrow: true, + __syscall_geteuid32__nothrow: true, + __syscall_getgid32__nothrow: true, + __syscall_getegid32__nothrow: true, +#if NODERAWFS + // NODERAWFS reports the real host process credentials (0 on Windows, which + // has no uid/gid concept). + __syscall_getuid32: () => process.getuid?.() ?? 0, + __syscall_geteuid32: () => process.geteuid?.() ?? 0, + __syscall_getgid32: () => process.getgid?.() ?? 0, + __syscall_getegid32: () => process.getegid?.() ?? 0, +#else + __syscall_getuid32: () => 0, + __syscall_geteuid32: () => 0, + __syscall_getgid32: () => 0, + __syscall_getegid32: () => 0, +#endif __syscall_dup3: (fd, newfd, flags) => { if (fd === newfd) return -{{{ cDefs.EINVAL }}}; if (flags & ~{{{ cDefs.O_CLOEXEC }}}) return -{{{ cDefs.EINVAL }}}; diff --git a/system/lib/libc/emscripten_syscall_stubs.c b/system/lib/libc/emscripten_syscall_stubs.c index e0e1f2f5158bf..d7743c81ef5a7 100644 --- a/system/lib/libc/emscripten_syscall_stubs.c +++ b/system/lib/libc/emscripten_syscall_stubs.c @@ -129,22 +129,6 @@ weak int __syscall_setdomainname(const char *name, size_t len) { return -EPERM; } -weak uid_t __syscall_getuid32(void) { - return 0; -} - -weak gid_t __syscall_getgid32(void) { - return 0; -} - -weak uid_t __syscall_geteuid32(void) { - return 0; -} - -weak gid_t __syscall_getegid32(void) { - return 0; -} - weak int __syscall_getresuid32(uid_t *ruid, uid_t *euid, uid_t *suid) { *ruid = 0; *euid = 0; diff --git a/system/lib/wasmfs/syscalls.cpp b/system/lib/wasmfs/syscalls.cpp index 757a2d7f21c46..1edee81b13f66 100644 --- a/system/lib/wasmfs/syscalls.cpp +++ b/system/lib/wasmfs/syscalls.cpp @@ -1864,6 +1864,13 @@ int __syscall_linkat(int olddirfd, return -EMLINK; } +// NODERAWFS credential reporting is implemented in the legacy JS syscall layer +// only. +uid_t __syscall_getuid32(void) { return 0; } +uid_t __syscall_geteuid32(void) { return 0; } +gid_t __syscall_getgid32(void) { return 0; } +gid_t __syscall_getegid32(void) { return 0; } + // epoll is implemented in the legacy (non-WASMFS) JS syscall layer only. int __syscall_epoll_create1(int flags) { return -ENOSYS; } diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 1dca8f07ac0cb..a35e21282107c 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 269157, - "a.out.nodebug.wasm": 588047, - "total": 857204, + "a.out.js": 269335, + "a.out.nodebug.wasm": 588128, + "total": 857463, "sent": [ "IMG_Init", "IMG_Load", @@ -240,9 +240,13 @@ "__syscall_ftruncate64", "__syscall_getcwd", "__syscall_getdents64", + "__syscall_getegid32", + "__syscall_geteuid32", + "__syscall_getgid32", "__syscall_getpeername", "__syscall_getsockname", "__syscall_getsockopt", + "__syscall_getuid32", "__syscall_ioctl", "__syscall_linkat", "__syscall_listen", @@ -1767,9 +1771,13 @@ "env.__syscall_ftruncate64", "env.__syscall_getcwd", "env.__syscall_getdents64", + "env.__syscall_getegid32", + "env.__syscall_geteuid32", + "env.__syscall_getgid32", "env.__syscall_getpeername", "env.__syscall_getsockname", "env.__syscall_getsockopt", + "env.__syscall_getuid32", "env.__syscall_ioctl", "env.__syscall_linkat", "env.__syscall_listen", @@ -2209,9 +2217,6 @@ "__subvti3", "__synccall", "__syscall_acct", - "__syscall_getegid32", - "__syscall_geteuid32", - "__syscall_getgid32", "__syscall_getgroups32", "__syscall_getpgid", "__syscall_getpid", @@ -2221,7 +2226,6 @@ "__syscall_getresuid32", "__syscall_getrusage", "__syscall_getsid", - "__syscall_getuid32", "__syscall_madvise", "__syscall_mincore", "__syscall_mlock", @@ -4636,8 +4640,11 @@ "$getdelim", "$getdents", "$getdomainname", + "$getegid", "$getentropy", "$getenv", + "$geteuid", + "$getgid", "$getgroups", "$gethostbyaddr", "$gethostbyaddr_r", @@ -4678,6 +4685,7 @@ "$gettext", "$gettid", "$gettimeofday", + "$getuid", "$getw", "$getwchar", "$glob", diff --git a/test/fs/test_getuid_noderawfs.c b/test/fs/test_getuid_noderawfs.c new file mode 100644 index 0000000000000..822f2d750b126 --- /dev/null +++ b/test/fs/test_getuid_noderawfs.c @@ -0,0 +1,23 @@ +/* + * Copyright 2024 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ + +#include +#include +#include +#include + +int main() { + // NODERAWFS reports the real host process credentials. Other backends report + // 0 and are covered by test/unistd/misc.c. + assert(getuid() == EM_ASM_INT({ return process.getuid(); })); + assert(geteuid() == EM_ASM_INT({ return process.geteuid(); })); + assert(getgid() == EM_ASM_INT({ return process.getgid(); })); + assert(getegid() == EM_ASM_INT({ return process.getegid(); })); + + printf("done\n"); + return 0; +} diff --git a/test/test_core.py b/test/test_core.py index fe18964eaae1d..801701171c127 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -5987,6 +5987,13 @@ def test_fs_utimensat_nofollow(self): def test_fs_fadvise_fallocate(self): self.do_runf('fs/test_fadvise_fallocate.c', 'done\n') + @no_windows('no uid/gid concept on windows') + def test_fs_getuid_noderawfs(self): + # The default backends report 0 and are covered by unistd/misc.c. This test + # verifies NODERAWFS reports the real host process credentials. + self.setup_noderawfs_test() + self.do_runf('fs/test_getuid_noderawfs.c', 'done\n') + @no_windows('https://github.com/emscripten-core/emscripten/issues/8882') @crossplatform @also_with_nodefs_both From 4ad07a78d5c650006146b1924d6a9003dbcba9ef Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 13 Jul 2026 15:04:13 -0700 Subject: [PATCH 2/2] Update test/fs/test_getuid_noderawfs.c --- test/fs/test_getuid_noderawfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fs/test_getuid_noderawfs.c b/test/fs/test_getuid_noderawfs.c index 822f2d750b126..e68566739e37d 100644 --- a/test/fs/test_getuid_noderawfs.c +++ b/test/fs/test_getuid_noderawfs.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Emscripten Authors. All rights reserved. + * Copyright 2026 The Emscripten Authors. All rights reserved. * Emscripten is available under two separate licenses, the MIT license and the * University of Illinois/NCSA Open Source License. Both these licenses can be * found in the LICENSE file.