Skip to content

kernel: make fstatat empty-path handling match Linux - #865

Closed
brandonpayton wants to merge 1 commit into
mainfrom
fix/fstatat-empty-path
Closed

kernel: make fstatat empty-path handling match Linux#865
brandonpayton wants to merge 1 commit into
mainfrom
fix/fstatat-empty-path

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jul 10, 2026

Copy link
Copy Markdown
Member

Why

The fstatat and statx system calls return file metadata. Linux's AT_EMPTY_PATH flag means that an empty pathname refers to an already-open file descriptor instead of a named path. Ruby uses this behavior when checking Homebrew download locks.

Make fstatat and statx handle Linux empty-path requests correctly. This is the path used by Ruby's File#stat / IO#stat, and therefore by Homebrew's download-lock code inside Kandelo.

Before this fix, Kandelo sent an empty pathname through ordinary path resolution. A regular-file descriptor then failed instead of statting the open file, so Homebrew aborted before downloading a package.

Root cause

sys_fstatat did not implement AT_EMPTY_PATH and did not validate its flags. The earlier version of this PR only special-cased a non-AT_FDCWD descriptor; against current main, that left the cwd form wrong, preserved the wrong no-flag errno, and silently accepted invalid flags.

What changed

  • fstatat(fd, "", ..., AT_EMPTY_PATH) stats the open descriptor itself, including non-directory descriptors such as regular files and pipes.
  • fstatat(AT_FDCWD, "", ..., AT_EMPTY_PATH) stats the current working directory.
  • An empty path without AT_EMPTY_PATH returns ENOENT.
  • Unsupported fstatat flags return EINVAL; AT_NO_AUTOMOUNT remains an accepted no-op.
  • statx accepts either synchronization selector, rejects selecting both, and passes the remaining lookup flags through the same checked path.
  • The POSIX status table records fstatat/statx as partial because Kandelo still represents cwd and directory OFDs by pathname after rename/unlink. This PR does not hide that broader directory-identity limitation.

This is a platform fix, not Homebrew-specific behavior.

ABI impact

No ABI bump is required. The syscall numbers, marshalling, structures, channel layout, exports, and guest constants are unchanged; existing binaries receive corrected behavior.

Exact-head validation

Current head: 590a9905aa48ade43784dceb496a7dbf4be28d47

  • Focused kernel tests: two fstatat empty-path tests passed, covering descriptor/cwd targets and Linux error behavior.
  • Focused kernel statx synchronization-flag test passed.
  • Fresh wasm32 and wasm64 musl sysroots built through scripts/dev-shell.sh.
  • The normal guest fixture passed through Kandelo for wasm32 and wasm64: 2/2 Vitest cases.
  • scripts/check-abi-version.sh passed at ABI 39; snapshot and generated bindings remain synchronized.
  • git diff --check passed.
  • Independent devil's-advocate review found no blocker in the final implementation, coverage, documentation, or ABI classification.

The original Homebrew download-lock symptom was not rerun end to end on this exact head. The new guest regression exercises the same public fstatat call and errno contract directly.

Fresh hosted staging, browser, kernel, host, libc, POSIX, and Sortix gates are required on this rewritten current-main head before ready-to-ship is applied. The old ABI-16-base run is not merge evidence for this version.

Implement Linux AT_EMPTY_PATH semantics for both open descriptors and AT_FDCWD, return ENOENT when the flag is absent, and reject unsupported fstatat/statx flags without rejecting statx synchronization modes. Add kernel coverage and wasm32/wasm64 guest ABI regression tests.
@brandonpayton
brandonpayton force-pushed the fix/fstatat-empty-path branch from d4c94ea to 590a990 Compare July 15, 2026 05:07
@brandonpayton brandonpayton changed the title kernel: handle AT_EMPTY_PATH in fstatat so File#stat on an fd works kernel: make fstatat empty-path handling match Linux Jul 15, 2026
@brandonpayton

Copy link
Copy Markdown
Member Author

Absorbed by rebase-merged #967. Main is now 6efb411 with the sealed tree b133bfa018f7e2bc84c4845edf2f945b2f844954, and ABI 41 activation completed successfully in run 29550069085. The absorption audit confirmed this PR\x27s behavior and tests are present in that merged tree, so this source PR is closed and its branch is deleted.

@brandonpayton
brandonpayton deleted the fix/fstatat-empty-path branch July 17, 2026 02:38
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.

1 participant