mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: cpu: Reject mis-sized ACPI CPU hotplug register accesses
Reject without asserting that the ACPI CPU hotplug register accesses match those that are specified by the ACPI definitions. Signed-off-by: Rob Bradford <rbradford@meta.com> Assisted-by: Claude:Opus-4.7
This commit is contained in:
+24
-6
@@ -3226,11 +3226,20 @@ impl BusDevice for AcpiCpuHotplugController {
|
|||||||
|
|
||||||
match offset {
|
match offset {
|
||||||
Self::CPU_SELECTION_OFFSET => {
|
Self::CPU_SELECTION_OFFSET => {
|
||||||
assert!(data.len() >= core::mem::size_of::<u32>());
|
if data.len() != size_of::<u32>() {
|
||||||
data[0..core::mem::size_of::<u32>()]
|
warn!(
|
||||||
.copy_from_slice(&self.selected_cpu.to_le_bytes());
|
"Invalid sized read of CPU selection register: {}",
|
||||||
|
data.len()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.copy_from_slice(&self.selected_cpu.to_le_bytes());
|
||||||
}
|
}
|
||||||
Self::CPU_STATUS_OFFSET => {
|
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 {
|
if self.selected_cpu < self.max_vcpus {
|
||||||
let state = &vcpu_states[usize::try_from(self.selected_cpu).unwrap()];
|
let state = &vcpu_states[usize::try_from(self.selected_cpu).unwrap()];
|
||||||
if state.active() {
|
if state.active() {
|
||||||
@@ -3255,11 +3264,20 @@ impl BusDevice for AcpiCpuHotplugController {
|
|||||||
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
|
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
|
||||||
match offset {
|
match offset {
|
||||||
Self::CPU_SELECTION_OFFSET => {
|
Self::CPU_SELECTION_OFFSET => {
|
||||||
assert!(data.len() >= core::mem::size_of::<u32>());
|
if data.len() != size_of::<u32>() {
|
||||||
self.selected_cpu =
|
warn!(
|
||||||
u32::from_le_bytes(data[0..core::mem::size_of::<u32>()].try_into().unwrap());
|
"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 => {
|
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 {
|
if self.selected_cpu < self.max_vcpus {
|
||||||
// This structure is not shared with the vCPU thread, therefore, holding the
|
// This structure is not shared with the vCPU thread, therefore, holding the
|
||||||
// lock for the entire function doesn't cause any deadlock.
|
// lock for the entire function doesn't cause any deadlock.
|
||||||
|
|||||||
Reference in New Issue
Block a user