xHCI: clear event TRB before state.finish() to prevent re-entrancy race
CRITICAL F1.1 from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §3.3: xHCI acknowledge() called state.finish() BEFORE releasing the event TRB. A re-entrant waker.wake() from the future could re-enter the reactor and re-match the same event TRB against a different state that happens to overlap in address range, causing wrong-state-match. Fix: call trb.reserved(false) BEFORE every state.finish() call site in acknowledge() and acknowledge_failed_transfer_trbs(). This ensures the event TRB is no longer in the live state set when the future re-wakes, so a re-entrant wake cannot re-match this TRB. Touches 4 call sites in irq_reactor.rs: - StateKind::CommandCompletion match arm - StateKind::Transfer match arm (transfer match) - StateKind::Transfer 'dead ring' branch - StateKind::Other match arm - acknowledge_failed_transfer_trbs function
This commit is contained in:
@@ -459,6 +459,9 @@ impl<const N: usize> IrqReactor<N> {
|
||||
};
|
||||
|
||||
// TODO: Validate the command TRB.
|
||||
// Release the event TRB before waking the future so a
|
||||
// re-entrant waker.wake() cannot re-match this TRB.
|
||||
trb.reserved(false);
|
||||
state.finish(Some(NextEventTrb {
|
||||
src_trb: Some(command_trb.clone()),
|
||||
event_trb: trb.clone(),
|
||||
@@ -489,6 +492,7 @@ impl<const N: usize> IrqReactor<N> {
|
||||
let src_trb = self.hci.get_transfer_trb(phys_ptr, ring_id);
|
||||
// Give the source transfer TRB together with the event TRB, to the future.
|
||||
let state = self.states.remove(index);
|
||||
trb.reserved(false);
|
||||
state.finish(Some(NextEventTrb {
|
||||
src_trb: src_trb,
|
||||
event_trb: trb.clone(),
|
||||
@@ -518,6 +522,7 @@ impl<const N: usize> IrqReactor<N> {
|
||||
if self.hci.with_ring(ring_id, |_ring| ()).is_none() {
|
||||
log::debug!("State {} is a dead transfer", index);
|
||||
let state = self.states.remove(index);
|
||||
trb.reserved(false);
|
||||
state.finish(Some(NextEventTrb {
|
||||
src_trb: None,
|
||||
//TODO: don't send this TRB as it may not be related
|
||||
@@ -529,6 +534,7 @@ impl<const N: usize> IrqReactor<N> {
|
||||
|
||||
StateKind::Other(trb_type) if trb_type as u8 == trb.trb_type() => {
|
||||
let state = self.states.remove(index);
|
||||
trb.reserved(false);
|
||||
state.finish(None);
|
||||
return;
|
||||
}
|
||||
@@ -557,6 +563,7 @@ impl<const N: usize> IrqReactor<N> {
|
||||
continue;
|
||||
}
|
||||
let state = self.states.remove(index);
|
||||
trb.reserved(false);
|
||||
state.finish(Some(NextEventTrb {
|
||||
event_trb: trb.clone(),
|
||||
src_trb: None,
|
||||
|
||||
Reference in New Issue
Block a user