vsock: vhost_user: vfio: Fix potential host memory overflow

The vsock packets that we're building are resolving guest addresses to
host ones and use the latter as raw pointers.
If the corresponding guest mapped buffer spans across several regions in
the guest, they will do so in the host as well. Since we have no
guarantees that host regions are contiguous, it may lead the VMM into
trying to access memory outside of its memory space.

For now we fix that by ensuring that the guest buffers do not span
across several regions. If they do, we error out.
Ideally, we should enhance the rust-vmm memory model to support safe
acces across host regions.

Fixes CVE-2019-18960

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz
2019-12-12 14:08:34 +01:00
committed by Sebastien Boeuf
parent 1e97d1413e
commit 664431ff14
7 changed files with 110 additions and 29 deletions

View File

@@ -6,6 +6,7 @@ use crate::vec_with_array_field;
use byteorder::{ByteOrder, LittleEndian};
use kvm_ioctls::*;
use std::collections::HashMap;
use std::convert::TryInto;
use std::ffi::CString;
use std::fmt;
use std::fs::{File, OpenOptions};
@@ -19,7 +20,7 @@ use std::sync::{Arc, RwLock};
use std::u32;
use vfio_bindings::bindings::vfio::*;
use vfio_ioctls::*;
use vm_device::ExternalDmaMapping;
use vm_device::{get_host_address_range, ExternalDmaMapping};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
use vmm_sys_util::eventfd::EventFd;
use vmm_sys_util::ioctl::*;
@@ -524,12 +525,11 @@ impl VfioDmaMapping {
impl ExternalDmaMapping for VfioDmaMapping {
fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> {
let user_addr = if let Some(addr) = self
.memory
.read()
.unwrap()
.get_host_address(GuestAddress(gpa))
{
let user_addr = if let Some(addr) = get_host_address_range(
&self.memory.read().unwrap(),
GuestAddress(gpa),
size.try_into().unwrap(),
) {
addr as u64
} else {
return Err(io::Error::new(