xhcid: cap protocol_speeds slice at max 15 (xHCI spec limit)
The PSIC field in xHCI Supported Protocol Capability is 4 bits, so its value is 0-15. Using an unbounded psic() for slicing risks OOB reads if a buggy controller reports 15 but the actual data is shorter (or absent). Cap at 15 per xHCI spec §7.2 and §4.16.1.1. This matches Linux 7.1 xhci_create_port_array() which uses kcalloc_node with the count for proper allocation.
This commit is contained in:
@@ -223,16 +223,24 @@ pub const SUPP_PROTO_CAP_PORT_SLOT_TYPE_SHIFT: u8 = 0;
|
||||
|
||||
impl SupportedProtoCap {
|
||||
pub unsafe fn protocol_speeds(&self) -> &[ProtocolSpeed] {
|
||||
// xHCI spec §7.2: PSIC is a 4-bit field (max 15).
|
||||
// xHCI spec §4.16.1.1: PSIV may be 0-15, so max 15 ProtocolSpeed entries.
|
||||
// Cap at 15 to prevent OOB reads from buggy controllers.
|
||||
// Cross-referenced with Linux 7.1 drivers/usb/host/xhci-mem.c
|
||||
// xhci_create_port_array() which uses kcalloc_node() with the
|
||||
// bounded PSIC count.
|
||||
let max_psic = (self.psic() as usize).min(15);
|
||||
slice::from_raw_parts(
|
||||
&self.protocol_speeds as *const u8 as *const _,
|
||||
self.psic() as usize,
|
||||
max_psic,
|
||||
)
|
||||
}
|
||||
pub unsafe fn protocol_speeds_mut(&mut self) -> &mut [ProtocolSpeed] {
|
||||
// XXX: Variance really is annoying sometimes.
|
||||
let max_psic = (self.psic() as usize).min(15);
|
||||
slice::from_raw_parts_mut(
|
||||
&self.protocol_speeds as *const u8 as *mut u8 as *mut _,
|
||||
self.psic() as usize,
|
||||
max_psic,
|
||||
)
|
||||
}
|
||||
pub fn rev_minor(&self) -> u8 {
|
||||
|
||||
Reference in New Issue
Block a user