fix(codex): reject profile FIFOs without blocking - #1263
Conversation
📝 WalkthroughWalkthroughOn non-Windows platforms, bounded vault reads now open files with ChangesFIFO read protection
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
b12244e to
61ec149
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Ingwannu
left a comment
There was a problem hiding this comment.
The O_NONBLOCK change is a sensible defense for direct readBounded callers, but the new regression test does not reach that code path and currently fails on the PR head. readNativeProfileVault() first calls assertNativeProfileMetadataLayout(), which rejects the FIFO as PROFILE_STORAGE_UNSAFE; the child only accepts VAULT_INVALID, so it exits 92 (locally: 15 pass, 1 fail; the macOS CI job also failed). Please make the test exercise a direct bounded-read surface such as the config/auth path, or explicitly test the existing metadata-layout rejection separately, and include child.stderr in the assertion message so future failures are diagnosable. I will re-review once the test proves the intended nonblocking boundary and CI is green.
61ec149 to
7c3fa54
Compare
Ingwannu
left a comment
There was a problem hiding this comment.
Re-checked rebased exact head 7c3fa541. The blocker is unchanged: the new test still calls readNativeProfileVault(), so assertNativeProfileMetadataLayout() rejects the FIFO as PROFILE_STORAGE_UNSAFE before the O_NONBLOCK open path is exercised. The child accepts only VAULT_INVALID and exits 92; exact-head result remains 15 pass / 1 fail. Please apply the requested direct bounded-read regression (or separate layout-contract assertion) rather than only rebasing the same patch.
Exercise the production config read path in a bounded subprocess so POSIX CI verifies O_NONBLOCK without the vault safety preflight masking it.
7c3fa54 to
49537ae
Compare
⏳ DRAFT
What to do
Review readiness checklist
0/4 boxes ticked. This PR stays in draft until every box above is ticked. |
|
Updated exact head The POSIX regression now creates a FIFO at Local Windows verification remains 15 passed / 1 POSIX-only skipped on Bun 1.3.14 and Bun 1.4.0-canary.1; the POSIX assertion now needs exact-head Linux/macOS CI confirmation before the readiness checklist is advanced. |
|
The fix is right and the test is wrong — CI is failing for that reason, not because of the code. I first concluded the defect did not exist: with a FIFO placed at the vault path before the call, The real defect is a TOCTOU race. A regular file that passes So The test creates the FIFO before the call, so it trips the upstream guard and never reaches the code you changed — it gets Suggested shape:
Asserting signal/timeout is what separates "hung" from "rejected quickly". Happy to take it once that lands. |
Records a campaign that gave a terminal disposition to every open bug issue and bug PR at the 2026-08-08 cutoff, and what it got wrong along the way. The unit carries the inventory and disposition matrix with file:line evidence per verdict, the rebase-and-co-author republish protocol, and per-work-phase implementation docs. Execution records cover the CI approval unblock, the first CI results, and the merges and closes. What the audits overturned is the more useful half. Two issues were queued for closure as resolved and were not - lidge-jun#1176 carried a maintainer comment from the same morning asking for a v2.11.0 retest, and lidge-jun#1024 rested on an upstream attribution the plan itself proposed to test and had not tested. lidge-jun#1155 was queued as an unreachable path and is reachable. lidge-jun#1263 was diagnosed as having no defect and has a real TOCTOU race, shown by contrast experiment. lidge-jun#1119 was described as fully absorbed and was not, so its coverage was recreated on dev before it was closed. Two execution faults are recorded as faults: lidge-jun#1202 was merged without checking its exact-head CI had concluded success, violating a reading rule written earlier in this same unit; and a public comment to a contributor made a false claim about stream defaulting, corrected on the PR. A transient six-failure test run is recorded as unexplained rather than dismissed as flaky, since its log was overwritten before the names could be preserved. Nothing in the build, typecheck, or test path reads from devlog/. privacy:scan passes; repo-hygiene 11 pass / 0 fail.
Summary
O_NONBLOCKon POSIX while retainingO_NOFOLLOW;Why
The bounded reader validates the opened descriptor with
fstat, but a POSIXopenSync(..., O_RDONLY)can block before that validation when an untrusted profile path is a FIFO with no writer. The size cap and regular-file check therefore never get a chance to reject it.Adding
O_NONBLOCKmakes the open return promptly. The existing descriptor check then rejects the FIFO as a non-regular file, while regular file, replacement-race, and bounded-read semantics remain unchanged.The regression is intentionally isolated in a child process. If the flag is removed later, the OS timeout terminates only the child and reports a deterministic test failure instead of freezing the entire suite.
Verification
tests/native-profile-store.test.ts15 passed, 1 POSIX-only test skipped.b22e0e6d0) on Windows: the same result.bun x tsc --noEmit: passed.bun scripts/privacy-scan.ts: passed.git diff --check: passed.The FIFO assertion is POSIX-only and could not run locally because this host has no WSL distribution; the draft intentionally leaves that OS-specific execution to Linux CI.
Security boundary
This narrows a local availability edge in the native-profile metadata reader. It does not broaden accepted file types, paths, permissions, or credential-store behavior. Symlinks remain rejected by
O_NOFOLLOW, and the descriptor must still be a regular file within the existing byte cap.Checklist
Ready for review; Linux CI and maintainer review remain pending.
Summary by CodeRabbit
Bug Fixes
Tests
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.