diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-10 00:05:13 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-10 00:05:13 +0000 |
commit | a57b3a7b25a50040693f941833627c8583b9a7ed (patch) | |
tree | 654c391a6c77c02d72e2d52b65eb6e1a042ef3a9 | |
parent | b6c5c3dc8dbe77cdf98afe889fc70734d92b2cf1 (diff) | |
parent | d3a0a4237549fbdc7211871c0280e7858ff013fc (diff) | |
download | crosvm-android13-qpr3-s7-release.tar.gz |
Snap for 9470583 from d3a0a4237549fbdc7211871c0280e7858ff013fc to tm-qpr3-releaseandroid-13.0.0_r83android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r56android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-release
Change-Id: I3cf3372fd54e3c0e7b6a455f5b65454a39421c3c
-rw-r--r-- | devices/src/virtio/queue.rs | 7 | ||||
-rw-r--r-- | vm_memory/src/guest_memory.rs | 23 |
2 files changed, 24 insertions, 6 deletions
diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index a436f748f..1e4d8bdfb 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -162,11 +162,8 @@ impl DescriptorChain { if self.len > 0 { match self.get_mem_regions() { Ok(regions) => { - if regions.iter().any(|r| { - self.mem - .checked_offset(r.gpa, r.len as u64 - 1u64) - .is_none() - }) { + // Each region in `self.regions` must be a contiguous range in `self.mem`. + if !regions.iter().all(|r| self.mem.is_valid_range(r.gpa, r.len as u64)) { return false; } } diff --git a/vm_memory/src/guest_memory.rs b/vm_memory/src/guest_memory.rs index 47c3ba4fd..7c5b4d407 100644 --- a/vm_memory/src/guest_memory.rs +++ b/vm_memory/src/guest_memory.rs @@ -315,7 +315,10 @@ impl GuestMemory { .any(|region| region.start() < end && start < region.end()) } - /// Returns the address plus the offset if it is in range. + /// Returns an address `addr + offset` if it's in range. + /// + /// This function doesn't care whether a region `[addr, addr + offset)` is in range or not. To + /// guarantee it's a valid range, use `is_valid_range()` instead. pub fn checked_offset(&self, addr: GuestAddress, offset: u64) -> Option<GuestAddress> { addr.checked_add(offset).and_then(|a| { if self.address_in_range(a) { @@ -326,6 +329,24 @@ impl GuestMemory { }) } + /// Returns true if the given range `[start, start + length)` is a valid contiguous memory + /// range available to the guest and it's backed by a single underlying memory region. + pub fn is_valid_range(&self, start: GuestAddress, length: u64) -> bool { + if length == 0 { + return false; + } + + let end = if let Some(end) = start.checked_add(length - 1) { + end + } else { + return false; + }; + + self.regions + .iter() + .any(|region| region.start() <= start && end < region.end()) + } + /// Returns the size of the memory region in bytes. pub fn num_regions(&self) -> u64 { self.regions.len() as u64 |