Skip to content

Handle a negative st_rdev like st_dev - #428

Open
zackees wants to merge 2 commits into
sunfishcode:mainfrom
zackees:fix/signed-rdev
Open

zackees wants to merge 2 commits into
sunfishcode:mainfrom
zackees:fix/signed-rdev

Conversation

@zackees

@zackees zackees commented Sep 17, 2026 •

Copy link
Copy Markdown

Fixes #427.

dev_t is signed on some platforms (on macOS it is i32). from_rustix already handles that for st_dev by sign-extending through i64, but st_rdev has the same type and went through u64::try_from(stat.st_rdev).unwrap(), which panics with TryFromIntError(()) when the device number is negative. We hit this on an x86_64 macOS host: symlink_metadata panics at metadata_ext.rs:171.

This applies the existing st_dev conversion to st_rdev and widens the existing comment to cover both. The function's #[allow(unused_comparisons)] already covers platforms where dev_t is unsigned. Sign-extending matches std: std::os::darwin::fs::MetadataExt::st_rdev returns st_rdev as u64.

There's no regression test, because a negative st_rdev can't be produced portably. The change mirrors the st_dev code a few lines above.

This PR is stacked on #429: the CI repairs are the first commit, and this st_rdev change follows them. Once #429 merges, this branch can be rebased onto main so #428 contains only this fix.

Validated locally: Rust 1.70 cargo test --workspace --features=fs_utf8,arf_strings; Windows x86_64-pc-windows-gnu test check; nightly cargo fuzz build --dev; and Rust 1.95 formatting. GitHub marked the workflow action_required; no checks have started yet.

If this is acceptable, a 4.0.4 patch release would let downstream users pick it up without a [patch]. Thanks!

dev_t is signed on some platforms (macOS: i32), and st_rdev has that type
just like st_dev. st_dev already sign-extends a negative value; st_rdev
went straight through u64::try_from(..).unwrap(), which panics with
TryFromIntError on a negative device number. Apply the same conversion,
which also matches std's MetadataExt::st_rdev (`st_rdev as u64`).
@zackees

zackees commented Sep 24, 2026

Copy link
Copy Markdown
Author

The fix worked but the CI is broken. I created a new or to fix the CI and rebased on top of that.

zackees added a commit to zackees/kernal-api that referenced this pull request Sep 25, 2026
Hosted Intel and Apple Silicon runners pass every test the Recovery guest
excluded as a macOS finding (exact-SHA run 36067778414), so what remains
excluded is guest-only:
- cap-primitives st_rdev panic: the guest reports negative device numbers;
  wait for sunfishcode/cap-std#428 rather than [patch].
- ENOTSUP from the guest filesystem's atomic renames, now also covering
  install_directory's RENAME_SWAP (documented to return the fs error).
- one two-core timing window.

Re-enabled in the guest: the PTY restore and owner-bound child tests (fixed
in #347) and the containment-state test, which passes there now.

owned_group_termination_reaches_the_grandchild failed intermittently in the
guest because Child::wait closes stdin first, letting the root read EOF and
exit 0 before the SIGKILL landed. Hold stdin across a bounded wait and
assert the root died by SIGKILL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

cap-primitives 4.0.3 panics with TryFromIntError on a negative macOS st_rdev

1 participant