summary refs log tree commit diff
path: root/sys_util
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2017-06-20 10:15:51 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-06-27 00:20:33 -0700
commit0584fe9fb2694fad6dc841a8215e8017c18b19c7 (patch)
tree0180ba9aaec5211b367b2656775a82dac2fe736f /sys_util
parent045c7133dd22e4cc5fe62af136c15b04a8b8a485 (diff)
downloadcrosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar.gz
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar.bz2
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar.lz
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar.xz
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.tar.zst
crosvm-0584fe9fb2694fad6dc841a8215e8017c18b19c7.zip
Limit types that can be read from guest memory
Not all types are safe to read from guest memory.  Any type with a
reference or pointer will be initialized to random bits that don't refer
to a valid address.  This can cause dangling pointer and general
unsafe behavior.

To fix this, limit types that can be read with read_obj to those that
implement the unsafe trait `DataInit`.  Provide implementations of
`DataInit` for intrinsic types that are obviously safe to initialize
with random data.

Implement the needed traits for bootparam types as they are read from
the kernel image directly.

Change-Id: I1040f5bc1b2fc4c58c87d8a2ce3f618edcf6f9b1
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/540750
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'sys_util')
-rw-r--r--sys_util/Cargo.toml1
-rw-r--r--sys_util/src/guest_memory.rs5
-rw-r--r--sys_util/src/lib.rs1
-rw-r--r--sys_util/src/mmap.rs7
4 files changed, 9 insertions, 5 deletions
diff --git a/sys_util/Cargo.toml b/sys_util/Cargo.toml
index de38025..a91b145 100644
--- a/sys_util/Cargo.toml
+++ b/sys_util/Cargo.toml
@@ -4,5 +4,6 @@ version = "0.1.0"
 authors = ["The Chromium OS Authors"]
 
 [dependencies]
+data_model = { path = "../data_model" }
 libc = "*"
 
diff --git a/sys_util/src/guest_memory.rs b/sys_util/src/guest_memory.rs
index 0dfb709..f7ad298 100644
--- a/sys_util/src/guest_memory.rs
+++ b/sys_util/src/guest_memory.rs
@@ -8,6 +8,7 @@ use std::io::{Read, Write};
 use std::result;
 use std::sync::Arc;
 
+use data_model::DataInit;
 use guest_address::GuestAddress;
 use mmap::MemoryMapping;
 
@@ -160,7 +161,7 @@ impl GuestMemory {
     /// #     Ok(num1 + num2)
     /// # }
     /// ```
-    pub fn read_obj_from_addr<T: Copy>(&self, guest_addr: GuestAddress) -> Result<T> {
+    pub fn read_obj_from_addr<T: DataInit>(&self, guest_addr: GuestAddress) -> Result<T> {
         self.do_in_region(guest_addr, |mapping, offset| {
             mapping
                 .read_obj(offset)
@@ -183,7 +184,7 @@ impl GuestMemory {
     ///         .map_err(|_| ())
     /// # }
     /// ```
-    pub fn write_obj_at_addr<T>(&self, val: T, guest_addr: GuestAddress) -> Result<()> {
+    pub fn write_obj_at_addr<T: DataInit>(&self, val: T, guest_addr: GuestAddress) -> Result<()> {
         self.do_in_region(guest_addr, move |mapping, offset| {
             mapping
                 .write_obj(val, offset)
diff --git a/sys_util/src/lib.rs b/sys_util/src/lib.rs
index f4bf241..a915202 100644
--- a/sys_util/src/lib.rs
+++ b/sys_util/src/lib.rs
@@ -4,6 +4,7 @@
 
 //! Small system utility modules for usage by other modules.
 
+extern crate data_model;
 extern crate libc;
 
 mod mmap;
diff --git a/sys_util/src/mmap.rs b/sys_util/src/mmap.rs
index 71b8d56..edd2a00 100644
--- a/sys_util/src/mmap.rs
+++ b/sys_util/src/mmap.rs
@@ -11,9 +11,10 @@ use std::ptr::null_mut;
 use std::os::unix::io::AsRawFd;
 
 use libc;
-
 use errno;
 
+use data_model::DataInit;
+
 #[derive(Debug)]
 pub enum Error {
     /// Requested memory out of range.
@@ -141,7 +142,7 @@ impl MemoryMapping {
     ///     let res = mem_map.write_obj(55u64, 16);
     ///     assert!(res.is_ok());
     /// ```
-    pub fn write_obj<T>(&self, val: T, offset: usize) -> Result<()> {
+    pub fn write_obj<T: DataInit>(&self, val: T, offset: usize) -> Result<()> {
         unsafe {
             // Guest memory can't strictly be modeled as a slice because it is
             // volatile.  Writing to it with what compiles down to a memcpy
@@ -170,7 +171,7 @@ impl MemoryMapping {
     ///     let num: u64 = mem_map.read_obj(32).unwrap();
     ///     assert_eq!(55, num);
     /// ```
-    pub fn read_obj<T: Copy>(&self, offset: usize) -> Result<T> {
+    pub fn read_obj<T: DataInit>(&self, offset: usize) -> Result<T> {
         if offset + std::mem::size_of::<T>() > self.size {
             return Err(Error::InvalidAddress);
         }