mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
misc: Mark memory region APIs as unsafe
To ensure that struct sizes are the same on 32-bit and 64-bit, various kernel APIs use __u64 (Rust u64) to represent userspace pointers. Userspace is expected to cast pointers to __u64 before passing them to the kernel, and cast kernel-provided __u64 to a pointer before using them. However, various safe APIs in Cloud Hypervisor took caller-provided u64 values and passed them to syscalls that treat them as userspace addresses. Therefore, passing bad u64 values would cause memory disclosure or corruption. The memory region APIs are one example of this, so mark them as unsafe. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
This commit is contained in:
committed by
Rob Bradford
parent
00f0b9e42c
commit
fdc19ad85e
@@ -1663,21 +1663,22 @@ impl VfioPciDevice {
|
||||
host_addr: host_addr as u64,
|
||||
};
|
||||
|
||||
// SAFETY: host_addr was allocated by mmap() and points to size
|
||||
// bytes of memory.
|
||||
unsafe {
|
||||
self.vm.create_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}
|
||||
.map_err(VfioPciError::CreateUserMemoryRegion)?;
|
||||
|
||||
region.user_memory_regions.push(user_memory_region);
|
||||
|
||||
let mem_region = self.vm.make_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
self.vm
|
||||
.create_user_memory_region(mem_region)
|
||||
.map_err(VfioPciError::CreateUserMemoryRegion)?;
|
||||
|
||||
if !self.iommu_attached {
|
||||
self.container
|
||||
.vfio_dma_map(
|
||||
@@ -1714,16 +1715,18 @@ impl VfioPciDevice {
|
||||
}
|
||||
|
||||
// Remove region
|
||||
let r = self.vm.make_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
if let Err(e) = self.vm.remove_user_memory_region(r) {
|
||||
// SAFETY: only valid entries are added to the user_memory_regions field
|
||||
// of the entries of self.common.mmio_regions.
|
||||
if let Err(e) = unsafe {
|
||||
self.vm.remove_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
} {
|
||||
error!("Could not remove the userspace memory region: {e}");
|
||||
}
|
||||
|
||||
@@ -1898,20 +1901,19 @@ impl PciDevice for VfioPciDevice {
|
||||
user_memory_region.start, user_memory_region.size, e
|
||||
);
|
||||
}
|
||||
|
||||
// Remove old region
|
||||
let old_mem_region = self.vm.make_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
self.vm
|
||||
.remove_user_memory_region(old_mem_region)
|
||||
.map_err(io::Error::other)?;
|
||||
// SAFETY: user_memory_regions has valid entries
|
||||
unsafe {
|
||||
self.vm.remove_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}
|
||||
.map_err(io::Error::other)?;
|
||||
|
||||
// Update the user memory region with the correct start address.
|
||||
if new_base > old_base {
|
||||
@@ -1921,18 +1923,18 @@ impl PciDevice for VfioPciDevice {
|
||||
}
|
||||
|
||||
// Insert new region
|
||||
let new_mem_region = self.vm.make_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
self.vm
|
||||
.create_user_memory_region(new_mem_region)
|
||||
.map_err(io::Error::other)?;
|
||||
// SAFETY: mmio_regions only has valid values
|
||||
unsafe {
|
||||
self.vm.create_user_memory_region(
|
||||
user_memory_region.slot,
|
||||
user_memory_region.start,
|
||||
user_memory_region.size,
|
||||
user_memory_region.host_addr,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}
|
||||
.map_err(io::Error::other)?;
|
||||
|
||||
// Map the moved mmio region to vfio container
|
||||
if !self.iommu_attached {
|
||||
|
||||
Reference in New Issue
Block a user