summary refs log tree commit diff
path: root/sys_util/src/shm.rs
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-05-30 18:31:02 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-04 20:29:25 +0000
commit127453d7eccdb6a903d0855fabb8f0935be90882 (patch)
tree65bd9f0b4c6b2a98c60bb2580949a93209c0f639 /sys_util/src/shm.rs
parent6a0bfb037a109030b69feb9dec4a546548636940 (diff)
downloadcrosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar.gz
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar.bz2
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar.lz
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar.xz
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.tar.zst
crosvm-127453d7eccdb6a903d0855fabb8f0935be90882.zip
eliminate mut from non-mut references
This manifested itself in a couple places that were turning shared
memory buffers into slices for the purposes of passing these slices to
`Read` and `Write` trait methods.

However, this required the removal of the methods that took `Read` and
`Write` instances. This was a convenient interface but impossible to
implement safely because making slices from raw pointers without
enforcing safety guarantees causes undefined behaviour in Rust. It turns
out lots of code in crosvm was using these interfaces indirectly, which
explains why this CL touches so much.

TEST=crosvm run
BUG=chromium:938767

Change-Id: I4ff40c98da6ed08a4a42f4c31f0717f81b1c5863
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1636685
Reviewed-by: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'sys_util/src/shm.rs')
-rw-r--r--sys_util/src/shm.rs59
1 files changed, 53 insertions, 6 deletions
diff --git a/sys_util/src/shm.rs b/sys_util/src/shm.rs
index a72fe70..bb008d9 100644
--- a/sys_util/src/shm.rs
+++ b/sys_util/src/shm.rs
@@ -4,7 +4,7 @@
 
 use std::ffi::CStr;
 use std::fs::File;
-use std::io::{Seek, SeekFrom};
+use std::io::{self, Read, Seek, SeekFrom, Write};
 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
 
 use libc::{
@@ -178,12 +178,62 @@ impl SharedMemory {
     }
 }
 
+impl Read for SharedMemory {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.fd.read(buf)
+    }
+}
+
+impl Read for &SharedMemory {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (&self.fd).read(buf)
+    }
+}
+
+impl Write for SharedMemory {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.fd.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.fd.flush()
+    }
+}
+
+impl Write for &SharedMemory {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (&self.fd).write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.fd).flush()
+    }
+}
+
+impl Seek for SharedMemory {
+    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+        self.fd.seek(pos)
+    }
+}
+
+impl Seek for &SharedMemory {
+    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+        (&self.fd).seek(pos)
+    }
+}
+
 impl AsRawFd for SharedMemory {
     fn as_raw_fd(&self) -> RawFd {
         self.fd.as_raw_fd()
     }
 }
 
+impl AsRawFd for &SharedMemory {
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}
+
 impl Into<File> for SharedMemory {
     fn into(self) -> File {
         self.fd
@@ -213,7 +263,6 @@ mod tests {
 
     use std::ffi::CString;
     use std::fs::read_link;
-    use std::io::repeat;
 
     use data_model::VolatileMemory;
 
@@ -312,8 +361,7 @@ mod tests {
         mmap1
             .get_slice(0, 4096)
             .expect("failed to get mmap slice")
-            .read_from(&mut repeat(0x45))
-            .expect("failed to fill mmap slice");
+            .write_bytes(0x45);
 
         for i in 0..4096 {
             assert_eq!(mmap2.get_ref::<u8>(i).unwrap().load(), 0x45u8);
@@ -337,8 +385,7 @@ mod tests {
         mmap1
             .get_slice(0, 4096)
             .expect("failed to get mmap slice")
-            .read_from(&mut repeat(0x45))
-            .expect("failed to fill mmap slice");
+            .write_bytes(0x45);
 
         for i in 0..4096 {
             assert_eq!(mmap2.get_ref::<u8>(i).unwrap().load(), 0);