diff options
author | Dylan Reid <dgreid@chromium.org> | 2020-03-27 19:07:59 +0000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-05 21:32:17 +0000 |
commit | 252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9 (patch) | |
tree | dc25f8bcc4d2923222a7552b999aede2ec321855 /devices/src/pci | |
parent | 146450b4569e86657d1d8c4ffe17524781aae7e3 (diff) | |
download | crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar.gz crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar.bz2 crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar.lz crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar.xz crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.tar.zst crosvm-252d5b3cf3fd7a48fe9d610b59e3d6da9f2c6fe9.zip |
handle mmap of large offsets on 32 bit systems
While only 32 bits of address can be mapped, that 32 bits can be offset by further than 32 bits in to a large file. As chirantan points out, the try_mmap call was already casting the usize to u64 on all architectures. Convert the usize offset in mmap to u64 and address users of the API as well. Change-Id: I67aed928ea521049fb51eb7aa61ea4de8b4d096c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2124879 Reviewed-by: Dylan Reid <dgreid@chromium.org> Tested-by: Dylan Reid <dgreid@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'devices/src/pci')
-rw-r--r-- | devices/src/pci/ac97_bus_master.rs | 10 | ||||
-rw-r--r-- | devices/src/pci/vfio_pci.rs | 2 |
2 files changed, 9 insertions, 3 deletions
diff --git a/devices/src/pci/ac97_bus_master.rs b/devices/src/pci/ac97_bus_master.rs index 5f4ca75..809f31f 100644 --- a/devices/src/pci/ac97_bus_master.rs +++ b/devices/src/pci/ac97_bus_master.rs @@ -5,6 +5,7 @@ use std; use std::collections::VecDeque; use std::convert::AsRef; +use std::convert::TryInto; use std::error::Error; use std::fmt::{self, Display}; use std::os::unix::io::{AsRawFd, RawFd}; @@ -106,6 +107,8 @@ type GuestMemoryResult<T> = std::result::Result<T, GuestMemoryError>; enum AudioError { // Failed to create a new stream. CreateStream(Box<dyn Error>), + // Invalid buffer offset received from the audio server. + InvalidBufferOffset, // Guest did not provide a buffer when needed. NoBufferAvailable, // Failure to read guest memory. @@ -124,6 +127,7 @@ impl Display for AudioError { match self { CreateStream(e) => write!(f, "Failed to create audio stream: {}.", e), + InvalidBufferOffset => write!(f, "Offset > max usize"), NoBufferAvailable => write!(f, "No buffer was available from the Guest"), ReadingGuestError(e) => write!(f, "Failed to read guest memory: {}.", e), RespondRequest(e) => write!(f, "Failed to respond to the ServerRequest: {}", e), @@ -610,7 +614,7 @@ fn get_buffer_offset( func_regs: &Ac97FunctionRegs, mem: &GuestMemory, index: u8, -) -> GuestMemoryResult<usize> { +) -> GuestMemoryResult<u64> { let descriptor_addr = func_regs.bdbar + u32::from(index) * DESCRIPTOR_LENGTH as u32; let buffer_addr_reg: u32 = mem .read_obj_from_addr(GuestAddress(u64::from(descriptor_addr))) @@ -673,7 +677,9 @@ fn next_guest_buffer<'a>( return Ok(None); } - let offset = get_buffer_offset(func_regs, mem, index)?; + let offset = get_buffer_offset(func_regs, mem, index)? + .try_into() + .map_err(|_| AudioError::InvalidBufferOffset)?; let frames = get_buffer_samples(func_regs, mem, index)? / DEVICE_CHANNEL_COUNT; Ok(Some(GuestBuffer { diff --git a/devices/src/pci/vfio_pci.rs b/devices/src/pci/vfio_pci.rs index 4d5ad9e..d1b6f2b 100644 --- a/devices/src/pci/vfio_pci.rs +++ b/devices/src/pci/vfio_pci.rs @@ -709,7 +709,7 @@ impl VfioPciDevice { let mmap_size = mmap.size; let guest_map_start = bar_addr + mmap_offset; let region_offset = self.device.get_region_offset(index); - let offset: usize = (region_offset + mmap_offset) as usize; + let offset = region_offset + mmap_offset; if self .vm_socket_mem .send(&VmMemoryRequest::RegisterMmapMemory { |