diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 599335600..c035ad6e2 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -3226,11 +3226,20 @@ impl BusDevice for AcpiCpuHotplugController { match offset { Self::CPU_SELECTION_OFFSET => { - assert!(data.len() >= core::mem::size_of::()); - data[0..core::mem::size_of::()] - .copy_from_slice(&self.selected_cpu.to_le_bytes()); + if data.len() != size_of::() { + warn!( + "Invalid sized read of CPU selection register: {}", + data.len() + ); + return; + } + data.copy_from_slice(&self.selected_cpu.to_le_bytes()); } Self::CPU_STATUS_OFFSET => { + if data.len() != 1 { + warn!("Invalid sized read of CPU status register: {}", data.len()); + return; + } if self.selected_cpu < self.max_vcpus { let state = &vcpu_states[usize::try_from(self.selected_cpu).unwrap()]; if state.active() { @@ -3255,11 +3264,20 @@ impl BusDevice for AcpiCpuHotplugController { fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option> { match offset { Self::CPU_SELECTION_OFFSET => { - assert!(data.len() >= core::mem::size_of::()); - self.selected_cpu = - u32::from_le_bytes(data[0..core::mem::size_of::()].try_into().unwrap()); + if data.len() != size_of::() { + warn!( + "Invalid sized write of CPU selection register: {}", + data.len() + ); + return None; + } + self.selected_cpu = u32::from_le_bytes(data.try_into().unwrap()); } Self::CPU_STATUS_OFFSET => { + if data.len() != 1 { + warn!("Invalid sized write of CPU status register: {}", data.len()); + return None; + } if self.selected_cpu < self.max_vcpus { // This structure is not shared with the vCPU thread, therefore, holding the // lock for the entire function doesn't cause any deadlock.