summary refs log tree commit diff
path: root/msg_socket/src/msg_on_socket.rs
diff options
context:
space:
mode:
authorJingkui Wang <jkwang@google.com>2018-11-20 11:01:05 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-21 05:53:03 -0800
commit7a9c6def98c92d12c825e0d427c54e178e6ee860 (patch)
tree81f5d1507d8b7c4c448bde3556d8640ff3cf371d /msg_socket/src/msg_on_socket.rs
parent6bfee45131d929a824e0e600920c17f606475b61 (diff)
downloadcrosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar.gz
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar.bz2
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar.lz
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar.xz
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.tar.zst
crosvm-7a9c6def98c92d12c825e0d427c54e178e6ee860.zip
msg_socket: fix msg_on_socket alignment issue
Instead of using unaligned memory. Allocate aligned memory and copy into it, we
were already doing an clone. There should be no overhead for this new
approach.

BUG=chromium:900962
TEST=build and run

Change-Id: I011d4c93a872d7d285e8898ff332f3ee1ef104a9
Reviewed-on: https://chromium-review.googlesource.com/1344225
Commit-Ready: Jingkui Wang <jkwang@google.com>
Tested-by: Jingkui Wang <jkwang@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'msg_socket/src/msg_on_socket.rs')
-rw-r--r--msg_socket/src/msg_on_socket.rs33
1 files changed, 28 insertions, 5 deletions
diff --git a/msg_socket/src/msg_on_socket.rs b/msg_socket/src/msg_on_socket.rs
index aca57e2..fd24043 100644
--- a/msg_socket/src/msg_on_socket.rs
+++ b/msg_socket/src/msg_on_socket.rs
@@ -151,6 +151,31 @@ rawfd_impl!(UdpSocket);
 rawfd_impl!(UnixListener);
 rawfd_impl!(UnixDatagram);
 
+// This trait is unsafe as it use uninitialized memory.
+// Please only implement it for primitive types.
+unsafe trait AlignedNew: Sized + DataInit {
+    unsafe fn from_unaligned(buffer: &[u8]) -> Option<Self> {
+        let mut value = std::mem::uninitialized::<Self>();
+        {
+            let value_mem = value.as_mut_slice();
+            if value_mem.len() != buffer.len() {
+                return None;
+            }
+            value_mem.copy_from_slice(buffer);
+        }
+        Some(value)
+    }
+}
+
+unsafe impl AlignedNew for u8 {}
+unsafe impl AlignedNew for u16 {}
+unsafe impl AlignedNew for u32 {}
+unsafe impl AlignedNew for u64 {}
+
+unsafe impl AlignedNew for Le16 {}
+unsafe impl AlignedNew for Le32 {}
+unsafe impl AlignedNew for Le64 {}
+
 // usize could be different sizes on different targets. We always use u64.
 impl MsgOnSocket for usize {
     fn msg_size() -> usize {
@@ -160,9 +185,8 @@ impl MsgOnSocket for usize {
         if buffer.len() < std::mem::size_of::<u64>() {
             return Err(MsgError::WrongMsgBufferSize);
         }
-        let t: u64 = Le64::from_slice(&buffer[0..Self::msg_size()])
+        let t: u64 = Le64::from_unaligned(&buffer[0..Self::msg_size()])
             .unwrap()
-            .clone()
             .into();
         Ok((t as usize, 0))
     }
@@ -187,9 +211,8 @@ macro_rules! le_impl {
                 if buffer.len() < std::mem::size_of::<$le_type>() {
                     return Err(MsgError::WrongMsgBufferSize);
                 }
-                let t = $le_type::from_slice(&buffer[0..Self::msg_size()])
-                    .unwrap()
-                    .clone();
+                let t = $le_type::from_unaligned(&buffer[0..Self::msg_size()])
+                    .unwrap();
                 Ok((t.into(), 0))
             }