Skip to content

test(rust): skip the vtab permission tests when the OS ignores mode bits - #992

Merged
thekevinscott merged 1 commit into
mainfrom
claude/issue-977-ochq4t
Aug 20, 2026
Merged

thekevinscott merged 1 commit into
mainfrom
claude/issue-977-ochq4t

Conversation

@thekevinbot

Copy link
Copy Markdown
Collaborator

Fixes #977

What

packages/rust/tests/vtab.rs::unreadable_file_yields_null_content_without_erroring_the_row chmods a fixture 0o000 and asserts content comes back NULL. Root bypasses permission bits, so the read succeeds, content is Some("classified"), and the assertion fails. The product is fine — the test's precondition simply cannot hold for a privileged process. The hosted sandbox runs as uid 0, so cargo test --workspace --features cli was never clean there and cargo mutants aborted on the unmutated baseline.

This probes the precondition instead of assuming it:

fn make_unreadable(path: &Path) -> bool {
    fs::set_permissions(path, fs::Permissions::from_mode(0o000)).unwrap();
    fs::read(path).is_err()
}

Both permission-dependent tests call it and bail with a note when it returns false.

Why probing, not geteuid() == 0

The issue suggested a euid check. Probing is better on two counts: it needs no unsafe (so no #[expect(unsafe_code, reason = ...)] against the crate's unsafe_code = "deny" lint) and no libc call, and it also covers a non-root process holding CAP_DAC_OVERRIDE, where a euid check would still let the test fail.

The skip is observable, not silent — it prints under --nocapture / --show-output:

test unreadable_file_yields_null_content_without_erroring_the_row ... skipped: this process bypasses file permission bits
ok

Slightly beyond the issue's scope

star_does_not_read_file_bodies shares the same chmod 0o000 precondition. It passed under root rather than failing, but only vacuously — the permission error it exists to prove is absent never existed. It gets the same guard, so a green run means the same thing everywhere.

Manual verification

Run in the hosted sandbox (uid 0), pre- and post-fix:

# RED, before the change, as root
$ cargo test -p dirsql --features cli --test vtab
test result: FAILED. 17 passed; 1 failed; 0 ignored
  left: Some("classified")
 right: None

# GREEN, after the change, as root
$ cargo test -p dirsql --features cli --test vtab
test result: ok. 18 passed; 0 failed; 0 ignored

# ...and the assertions still really run for an unprivileged user
$ setpriv --reuid=65534 --regid=65534 --clear-groups \
    target/debug/deps/vtab-60ae893bf0b3098f --nocapture unreadable star_does
test star_does_not_read_file_bodies ... ok
test unreadable_file_yields_null_content_without_erroring_the_row ... ok
test result: ok. 2 passed; 0 failed

The uid-65534 run printed no skip line, which is the point: the guard is inert for a normal developer and for CI, and the two tests still carry their original teeth.

Whole Rust suite under uid 0 is now clean: cargo test --workspace --features cli → exit 0, zero failures (was 1 failure before).

Gates run locally

Gate Result
cargo test --workspace --features cli exit 0
cargo fmt --check -p dirsql exit 0
cargo clippy --workspace -- -D warnings (CI's exact invocation) clean
rust unit colocated-test exit 0
rust unit lint exit 0
rust integration lint exit 0
rust unit mutation --base origin/main exit 0 — 0 mutants tested (diff is test-only)
dirsql-checks changelog-gate exit 0 — no fragment owed
python + ts e2e verify exit 0 each — attestations stay fresh

E2E Verification

N/A - test-only (one file, packages/rust/tests/vtab.rs; no source under packages/rust/src, packages/ts/src, packages/python/src, or packages/ts/napi is touched). Both packages' e2e verify gates were still run locally and pass — [e2e].extra_scope names packages/rust/src, not packages/rust/tests, so neither attestation goes stale.

Changelog / Migrations

  • Changelog fragment not required — changelog_gate's decide.py classifies packages/<pkg>/tests?/ as test, not source. Verified by running the gate against this diff (exit 0).
  • Migration fragment not required — no public API change, no behavior change; test-only.

PARITY.md needs no update: no SDK public API surface changed.

Red/green note

Red/green's pushed-CI-RED gate does not apply here. The change adds no product behavior — it corrects a test's handling of a precondition the OS refuses to grant. CI runs as a non-root user, where behavior before and after is byte-identical, so there is no CI-observable RED to push. The RED that exists is the local reproduction above (uid 0, pre-fix), which the fix flips to green.


Generated by Claude Code

`unreadable_file_yields_null_content_without_erroring_the_row` chmods a
fixture 0o000 and asserts `content` comes back NULL. Root bypasses
permission bits, so the read succeeds and the assertion fails -- the
product is fine, the test's precondition just cannot hold for a
privileged process. The hosted sandbox runs as uid 0, so
`cargo test --workspace --features cli` was never clean there and
`cargo mutants` aborted on the unmutated baseline.

Probe the precondition instead of asserting it: `make_unreadable` chmods
the file and reports whether a read actually fails, and both permission
tests bail out with a note when it does not. Probing beats a
`geteuid() == 0` check -- it needs no `unsafe`/libc, and it also covers a
non-root process holding CAP_DAC_OVERRIDE.

`star_does_not_read_file_bodies` shares the precondition. It passed under
root rather than failing, but only vacuously, so it gets the same guard.

Fixes #977
@thekevinscott
thekevinscott merged commit f14b1e4 into main Aug 20, 2026
77 checks passed
@thekevinscott
thekevinscott deleted the claude/issue-977-ochq4t branch August 20, 2026 20:23
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.

vtab permission test fails for any root user, so the Rust suite is never clean in the hosted sandbox

3 participants