From 43f0dd6d253a87b9d8b99c5cda3047dc9e740f84 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 14 Sep 2021 17:06:39 +0100 Subject: [PATCH] devices: ioapic: Increase robustness of IOAPIC operations Validate the size of I/O reads and check that no request is made to an out of bounds index (which would cause a panic.) Signed-off-by: Rob Bradford --- devices/src/ioapic.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/devices/src/ioapic.rs b/devices/src/ioapic.rs index 881c261e2..08b2355e9 100644 --- a/devices/src/ioapic.rs +++ b/devices/src/ioapic.rs @@ -149,7 +149,10 @@ impl VersionMapped for IoapicState {} impl BusDevice for Ioapic { fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) { - assert!(data.len() == 4); + if data.len() != std::mem::size_of::() { + warn!("Invalid read size on IOAPIC: {}", data.len()); + return; + } debug!("IOAPIC_R @ offset 0x{:x}", offset); @@ -166,7 +169,10 @@ impl BusDevice for Ioapic { } fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option> { - assert!(data.len() == 4); + if data.len() != std::mem::size_of::() { + warn!("Invalid write size on IOAPIC: {}", data.len()); + return None; + } debug!("IOAPIC_W @ offset 0x{:x}", offset); @@ -226,6 +232,10 @@ impl Ioapic { IOAPIC_REG_ID => self.id_reg = (val >> 24) & 0xf, IOWIN_OFF..=REG_MAX_OFFSET => { let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8); + if index > NUM_IOAPIC_PINS { + warn!("IOAPIC index out of range: {}", index); + return; + } if is_high_bits { self.reg_entries[index] &= 0xffff_ffff; self.reg_entries[index] |= u64::from(val) << 32; @@ -259,6 +269,10 @@ impl Ioapic { IOAPIC_REG_ID | IOAPIC_REG_ARBITRATION_ID => (self.id_reg & 0xf) << 24, IOWIN_OFF..=REG_MAX_OFFSET => { let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8); + if index > NUM_IOAPIC_PINS { + warn!("IOAPIC index out of range: {}", index); + return 0; + } if is_high_bits { (self.reg_entries[index] >> 32) as u32 } else {