fix(threading): avoid invalid Channel/FIFO read patterns - #31107
Dicklesworthstone wants to merge 1 commit into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughRefactors Channel read paths by adding a mutex-guarded helper ChangesChannel read path consolidation
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
620f98d to
5a63c2b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/collections/linear_fifo.rs`:
- Around line 283-285: The current DynamicBuffer<T>::as_mut_slice() (via
assume_init_slice_mut()) creates &mut [T] over uninitialized memory which is UB
for non‑"any‑bit‑pattern" types like bool; update the buffer API used by
LinearFifo and Channel::init_dynamic() to avoid creating typed references to
uninitialized memory: either add a trait bound (e.g., require T: Pod) on
DynamicBuffer/LinearFifo/Channel so assume_init_slice_mut() is only used for POD
types, or change the trait to expose &mut [MaybeUninit<T>] / raw pointers to
MaybeUninit<T> and perform unsafe copies/rotations with ptr::copy /
ptr::copy_nonoverlapping on the MaybeUninit storage (e.g., replace calls to
as_mut_slice() and buf.as_mut_slice().as_mut_ptr() with MaybeUninit-aware
operations) so no &mut T is formed for uninitialized slots.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3d349eaa-9682-4315-aed3-f72a76321044
📒 Files selected for processing (2)
src/collections/linear_fifo.rssrc/threading/channel.rs
Audit EXP-033 showed the single-item Channel read path could build a typed &mut [T; 1] over MaybeUninit storage before any T existed. That is invalid for values with Rust validity requirements, and the witness reports Miri UB while reading the uninitialized bool-shaped slot. Route try_read_item/read_item through the same locked FIFO pop used by read_items instead of fabricating a temporary initialized slice. The shared helper checks emptiness before popping, preserves the closed-channel behavior, and still avoids holding the UnsafeCell buffer borrow across Condition::wait(). Fresh-eyes review also found that write_items was appending the whole input slice on every loop iteration while advancing pushed by one. Write one queued item per successful iteration instead, matching the loop's blocking/partial-write accounting. Running the multi-item dynamic-buffer test under Miri then exposed neighboring LinearFifo::realign stacked-borrows issues: the overlapping copies derived shared raw pointers and mutable raw pointers from the same slice. Derive all source and destination pointers from one mutable raw pointer instead. Add tests for the bool payload read path, multi-item writes appending each item exactly once, and the wrapped realign path. Verification: - bun run fmt:rust - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly test -p bun_threading channel::tests - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-miri-target cargo +nightly miri test -p bun_threading channel::tests - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly check -p bun_threading - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly test -p bun_collections linear_fifo - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-miri-target cargo +nightly miri test -p bun_collections linear_fifo_realign_wrapped_buffer - env CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly check -p bun_collections - git diff --check
5a63c2b to
b471ab4
Compare
What changed
This fixes the audit EXP-033 Channel single-item read shape in
bun_threading.try_read_item()andread_item()previously allocated[MaybeUninit<T>; 1], cast that storage to&mut [T; 1], and then routed through the slice-based read APIs. That fabricates a typed mutable reference before a validTexists in the slot. For validity-sensitive payloads such asbool, the audit witness reports Miri UB while reading the uninitialized slot:The single-item methods now pop directly from the locked FIFO through a shared helper, avoiding the temporary uninitialized
Treference entirely. The helper preserves the existing empty/closed-channel behavior and still avoids holding theUnsafeCellbuffer borrow acrossCondition::wait().During review, I also found a neighboring channel write bug:
write_items()appended the entire input slice on every loop iteration while advancingpushedby one. That could duplicate multi-item writes (or return the wrong partial count for fixed buffers). It now writes exactlyitems[pushed]per successful iteration, matching the loop's accounting and blocking behavior.Running the new dynamic-buffer multi-item test under Miri then exposed nearby
LinearFifo::realignstacked-borrows issues: overlapping copies derived shared raw pointers and mutable raw pointers from the same slice. Both realign copy paths now derive source and destination from one mutable raw pointer.Test coverage
Added coverage for:
Channel<bool>single-item reads, so the validity-sensitive payload case is exercised directly under MiriLinearFifo::realign, which exercises the second raw-copy branch under MiriVerification
bun run fmt:rustenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly test -p bun_threading channel::testsenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-miri-target cargo +nightly miri test -p bun_threading channel::testsenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly check -p bun_threadingenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly test -p bun_collections linear_fifoenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-miri-target cargo +nightly miri test -p bun_collections linear_fifo_realign_wrapped_bufferenv CARGO_TARGET_DIR=/tmp/bun-channel-fix-target cargo +nightly check -p bun_collectionsgit diff --checkenv CARGO_TARGET_DIR=/tmp/bun-channel-clean-target cargo +nightly check --workspacefrom a cleanHEADsnapshotThe workspace check only emitted existing warnings.