diff options
author | Jingkui Wang <jkwang@google.com> | 2018-11-20 11:01:05 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-11-21 05:53:03 -0800 |
commit | 7a9c6def98c92d12c825e0d427c54e178e6ee860 (patch) | |
tree | 81f5d1507d8b7c4c448bde3556d8640ff3cf371d /msg_socket/src/msg_on_socket.rs | |
parent | 6bfee45131d929a824e0e600920c17f606475b61 (diff) | |
download | crosvm-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.rs | 33 |
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)) } |