From 7a9c6def98c92d12c825e0d427c54e178e6ee860 Mon Sep 17 00:00:00 2001 From: Jingkui Wang Date: Tue, 20 Nov 2018 11:01:05 -0800 Subject: [PATCH] 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 Tested-by: Jingkui Wang Reviewed-by: Daniel Verkamp --- msg_socket/src/msg_on_socket.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/msg_socket/src/msg_on_socket.rs b/msg_socket/src/msg_on_socket.rs index aca57e23a4..fd24043a1e 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 { + let mut value = std::mem::uninitialized::(); + { + 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::() { 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)) }