summary refs log tree commit diff
path: root/sys_util/src/mmap.rs
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2018-01-04 10:34:10 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-01-05 21:14:12 -0800
commitbf879d6bcda7b8f1d8358ea02ae6c834abaef045 (patch)
tree6f43b23726b04f3670a9b9071920e0f605864c2f /sys_util/src/mmap.rs
parent00600771148778e423b62614cc069b6c177bd660 (diff)
downloadcrosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar.gz
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar.bz2
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar.lz
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar.xz
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.tar.zst
crosvm-bf879d6bcda7b8f1d8358ea02ae6c834abaef045.zip
mmap: Bounds check offset on read
The other functions in mmap check that the offset doesn't overflow. The
kernel_loader fuzzer found that read forgot to check.

Change-Id: Ifc89dbe40345c5923a5cf29c9f29e810e9e1a1e8
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/850542
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'sys_util/src/mmap.rs')
-rw-r--r--sys_util/src/mmap.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/sys_util/src/mmap.rs b/sys_util/src/mmap.rs
index 683632d..73b3ff6 100644
--- a/sys_util/src/mmap.rs
+++ b/sys_util/src/mmap.rs
@@ -198,7 +198,11 @@ impl MemoryMapping {
             // Guest memory can't strictly be modeled as a slice because it is
             // volatile.  Writing to it with what compiles down to a memcpy
             // won't hurt anything as long as we get the bounds checks right.
-            if offset + std::mem::size_of::<T>() > self.size {
+            let mem_end = match offset.checked_add(std::mem::size_of::<T>()) {
+                None => return Err(Error::InvalidAddress),
+                Some(m) => m,
+            };
+            if mem_end > self.size() {
                 return Err(Error::InvalidAddress);
             }
             std::ptr::write_volatile(&mut self.as_mut_slice()[offset..] as *mut _ as *mut T, val);
@@ -223,7 +227,11 @@ impl MemoryMapping {
     ///     assert_eq!(55, num);
     /// ```
     pub fn read_obj<T: DataInit>(&self, offset: usize) -> Result<T> {
-        if offset + std::mem::size_of::<T>() > self.size {
+        let mem_end = match offset.checked_add(std::mem::size_of::<T>()) {
+            None => return Err(Error::InvalidAddress),
+            Some(m) => m,
+        };
+        if mem_end > self.size() {
             return Err(Error::InvalidAddress);
         }
         unsafe {
@@ -259,7 +267,10 @@ impl MemoryMapping {
     pub fn read_to_memory<F>(&self, mem_offset: usize, src: &mut F, count: usize) -> Result<()>
         where F: Read
     {
-        let mem_end = mem_offset + count;
+        let mem_end = match mem_offset.checked_add(count) {
+            None => return Err(Error::InvalidRange(mem_offset, count)),
+            Some(m) => m,
+        };
         if mem_end > self.size() {
             return Err(Error::InvalidRange(mem_offset, count));
         }