Skip to content

Report host uid/gid credentials under NODERAWFS#27319

Open
guybedford wants to merge 1 commit into
emscripten-core:mainfrom
guybedford:getuid-noderawfs
Open

Report host uid/gid credentials under NODERAWFS#27319
guybedford wants to merge 1 commit into
emscripten-core:mainfrom
guybedford:getuid-noderawfs

Conversation

@guybedford

Copy link
Copy Markdown
Collaborator

Reports the real host process credentials for getuid/geteuid/getgid/getegid under NODERAWFS (via node's process.get*id()), rather than the hardcoded 0.

These move from weak C stubs into the JS syscall layer, since a weak C definition otherwise wins 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 stay EPERM: musl routes them all through __setxid, which emscripten stubs out because it relies on dynamic (numeric) syscall dispatch that the compile-time syscall mapping can't provide.

Tested across MEMFS/NODEFS/NODERAWFS (test_fs_getuid).

Made with AI assistance under my review

Comment thread test/fs/test_getuid.c Outdated
#else
// Every other backend reports 0.
assert(getuid() == 0);
assert(geteuid() == 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't these already tested in test/unistd/misc.c?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, removed that branch to just test the NODERAWFS path only.

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm % testing question

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 test/fs coverage across MEMFS/NODEFS/NODERAWFS: test_fs_getuid.
Comment thread test/test_core.py
# 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.c', 'done\n')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename the test and the source file test_getuid_noderaws?

@kleisauke

Copy link
Copy Markdown
Collaborator

Would it make more sense to do this under NODE_HOST_ENV rather than NODERAWFS?

@sbc100

sbc100 commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Would it make more sense to do this under NODE_HOST_ENV rather than NODERAWFS?

I'm not sure. NODE_HOST_ENV is specifically about the environment variables. I guess it depends how granular folks want to be in exposing the underlying OS primitives.

These uid/gid settings seems like they should probably also go hand in hard with NODERAWFS since UID and GID number are exports via the filesystem ownership bits (fstat). Unless we also expose getgid etc, users of NODERAWFS will have a confusing mixed picture of the UID space (with the functions reports different IDs to fstat).

@kleisauke

Copy link
Copy Markdown
Collaborator

I see. I thought that decoupling it from NODERAWFS would also make it work with WASMFS. I think my confusion came from these lines:

// When building with WASMFS the socket syscalls are implemented natively in
// libwasmfs.a.
#if PROXY_POSIX_SOCKETS == 0 && WASMFS == 0

That would make me assume that libsyscall.js is also used under WASMFS too, which isn't the case.

if (!WASMFS) {
libraries.push('libsyscall.js');
}

(i.e. && WASMFS == 0 always evaluates to true)

That said, adding new features like this (and 16fa2c6) only to the legacy JS filesystem would make it more difficult to enable WASMFS by default in the future.

@sbc100

sbc100 commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

I see. I thought that decoupling it from NODERAWFS would also make it work with WASMFS. I think my confusion came from these lines:

// When building with WASMFS the socket syscalls are implemented natively in
// libwasmfs.a.
#if PROXY_POSIX_SOCKETS == 0 && WASMFS == 0

That would make me assume that libsyscall.js is also used under WASMFS too, which isn't the case.

if (!WASMFS) {
libraries.push('libsyscall.js');
}

(i.e. && WASMFS == 0 always evaluates to true)
That said, adding new features like this (and 16fa2c6) only to the legacy JS filesystem would make it more difficult to enable WASMFS by default in the future.

While its true that extending the old FS makes more work for the WASMFS transition, I don't think that means we shouldn't do it.

I think we are still at the point where its reasonable for some folks to work on the old FS (and make changes like this) while other try to improve WASMFS. I'm personally not 100% convinced the WASMFS even makes sense for NODERAWFS case. For example there is no point the WASMFS in-memory FS cache when using NODERAWFS.. we just want the system calls to be mapped as directly ass possible to the OS in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants