diff options
author | Dylan Reid <dgreid@chromium.org> | 2018-01-04 10:34:10 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-01-05 21:14:12 -0800 |
commit | bf879d6bcda7b8f1d8358ea02ae6c834abaef045 (patch) | |
tree | 6f43b23726b04f3670a9b9071920e0f605864c2f /sys_util/src/mmap.rs | |
parent | 00600771148778e423b62614cc069b6c177bd660 (diff) | |
download | crosvm-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.rs | 17 |
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)); } |