From 51ae15674a4c629fe709f64012202a1ee9a21cc0 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Mon, 27 Jul 2026 16:08:04 +0900 Subject: [PATCH] xHCI: clear event TRB before state.finish() to prevent re-entrancy race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- drivers/usb/xhcid/src/xhci/irq_reactor.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/xhcid/src/xhci/irq_reactor.rs b/drivers/usb/xhcid/src/xhci/irq_reactor.rs index c89efd04d8..ee3fe5aaf3 100644 --- a/drivers/usb/xhcid/src/xhci/irq_reactor.rs +++ b/drivers/usb/xhcid/src/xhci/irq_reactor.rs @@ -459,6 +459,9 @@ impl IrqReactor { }; // 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 IrqReactor { 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 IrqReactor { 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 IrqReactor { 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 IrqReactor { continue; } let state = self.states.remove(index); + trb.reserved(false); state.finish(Some(NextEventTrb { event_trb: trb.clone(), src_trb: None,