Preserve descriptor identity through devfs aliases - #876
Open
brandonpayton wants to merge 1 commit into
Open
Conversation
Member
Author
|
CI note: the red
This is the same external baseline failure documented on #875. No branch change is warranted; rerun the gate after #867 establishes the ABI 18 publication baseline. |
Following stat and fstatat calls on /dev/fd/N and the stdio aliases now return the referenced descriptor's authoritative metadata. No-follow calls report stable devfs symlink metadata, readlink exposes the alias target, and O_NOFOLLOW rejects the final symlink. Keep devfs directory, getdents, and lstat device/inode metadata coherent. Add a guest regression exercised through both NodeKernelHost and BrowserKernel. This fixes GNU coreutils mistaking /dev/null for stdin without changing the ABI.
brandonpayton
force-pushed
the
fix/devfs-inode-identity
branch
from
July 12, 2026 03:43
c832d4d to
35f0455
Compare
Member
Author
ABI 18 rebaseRebased the single semantic commit onto current ABI 18 main
I did not rerun the local runtime suites for this history-only rebase. Hosted CI is now running against the ABI 18 merge base and the repaired ABI 18 binary ledger; the prior ABI 16 materialization failure is superseded. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contract
Make
/dev/fd/Nand/dev/std{in,out,err}truthful descriptor aliases. Path-based metadata that follows an alias must describe the same open file description asfstat(N); no-follow metadata must describe the devfs symlink itself.Root cause
The Rust kernel intercepted these paths before host VFS delegation, but
sys_statandsys_fstatatreturned a hard-coded character-device stat instead of consulting the process fd table. With captured stdio, the measured guest tuples were:st_devst_inost_modestat("/dev/stdin")before020666fstat(0)010600GNU coreutils' descriptor heuristic interpreted that false character device as stdin while evaluating
/dev/null, then rejected an ordinary copy as replacing the source.host/src/vfs/device-fs.tsis not on this syscall path; the mismatch was entirely in the shared kernel.Change
stat,fstatat, and thereforestatxcalls throughsys_fstatfor the referenced descriptor.lstatandAT_SYMLINK_NOFOLLOW; implement matchingreadlinktargets and reject final-component aliases underO_NOFOLLOW./dev,/dev/fd/Ndirectory entries, and symlink stats in the same devfs device/inode namespace.NodeKernelHostand real ChromiumBrowserKernelpaths.Node.js and browser use the same Rust kernel implementation. There are no host-specific branches in this fix.
ABI and artifacts
No syscall number, argument meaning, marshalled layout, channel field, export, custom section, or generated binding changed. This corrects an existing POSIX/devfs behavior contract for already-built programs, so
ABI_VERSIONis unchanged and no package or VFS artifact rebuild is required. The ABI snapshot and generated bindings remain byte-for-byte current.Validation
./scripts/dev-shell.sh bash scripts/ci-run-test-suite.sh cargo-kernel- 968 passed, 0 failed../scripts/dev-shell.sh bash -c 'rm -rf host/dist && cd host && npx vitest run test/dev-fd-stat.test.ts'- passed../scripts/dev-shell.sh bash -c 'rm -rf host/dist && cd apps/browser-demos && CI=1 KANDELO_PLAYWRIGHT_PORT=5297 npx playwright test test/dev-fd-stat.spec.ts --project=chromium'- passed.cp /dev/null /tmp/emptythroughNodeKernelHost- exit 0, empty stdout/stderr../scripts/dev-shell.sh bash scripts/check-abi-version.sh- snapshot, C header, TypeScript bindings, andABI_VERSIONconsistent../scripts/dev-shell.sh bash scripts/ci-run-test-suite.sh posix- 174 passed, 3 declared XFAIL, 2 unsupported, 0 unexpected failures../scripts/dev-shell.sh bash scripts/run-libc-tests.sh functional stat- passed../scripts/dev-shell.sh bash scripts/run-sortix-tests.sh basic sys_stat/stat sys_stat/lstat sys_stat/fstat sys_stat/fstatat- 4 passed.git diff --check- passed.Not run
sysroot64/hello64.wasm. The full Vitest command was not rerun end-to-end.cargo fmtis unavailable in the canonical dev shell (cargo: no such command: fmt); the Rust diff is manually rustfmt-shaped andgit diff --checkpasses.