From f6563b26b948792bef18eae88f935bf71c2c25be Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Wed, 13 Feb 2019 18:38:00 -0800 Subject: [PATCH] Ensure cmsg buffer alignment --- quinn/src/platform/cmsg.rs | 3 +++ quinn/src/platform/linux.rs | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/quinn/src/platform/cmsg.rs b/quinn/src/platform/cmsg.rs index 0a3bd6ab2..a0a034b17 100644 --- a/quinn/src/platform/cmsg.rs +++ b/quinn/src/platform/cmsg.rs @@ -1,5 +1,8 @@ use std::{mem, ptr}; +#[repr(align(8))] // Conservative bound for align_of +pub struct Aligned(pub T); + /// Helper to encode a series of control messages ("cmsgs") to a buffer for use in `sendmsg`. /// /// The operation must be "finished" for the msghdr to be usable, either by calling `finish` diff --git a/quinn/src/platform/linux.rs b/quinn/src/platform/linux.rs index f01b4e1d0..d0da16430 100644 --- a/quinn/src/platform/linux.rs +++ b/quinn/src/platform/linux.rs @@ -25,6 +25,10 @@ impl super::UdpExt for UdpSocket { assert_eq!(CMSG_LEN, unsafe { libc::CMSG_SPACE(mem::size_of::() as _) as usize }); + assert!( + mem::align_of::() <= mem::align_of::>(), + "control message buffers will be misaligned" + ); let addr = self.local_addr()?; @@ -88,12 +92,13 @@ impl super::UdpExt for UdpSocket { msg_controllen: 0, msg_flags: 0, }; - let mut ctrl: [u8; CMSG_LEN] = unsafe { mem::uninitialized() }; + let mut ctrl: cmsg::Aligned<[u8; CMSG_LEN]> = + cmsg::Aligned(unsafe { mem::uninitialized() }); let is_ipv4 = match remote { SocketAddr::V4(_) => true, SocketAddr::V6(ref addr) => addr.ip().segments().starts_with(&[0, 0, 0, 0, 0, 0xffff]), }; - let mut encoder = cmsg::Encoder::new(&mut hdr, &mut ctrl); + let mut encoder = unsafe { cmsg::Encoder::new(&mut hdr, &mut ctrl.0) }; if is_ipv4 { encoder.push(libc::IPPROTO_IP, libc::IP_TOS, ecn); } else { @@ -119,13 +124,14 @@ impl super::UdpExt for UdpSocket { iov_base: buf.as_ptr() as *mut _, iov_len: buf.len(), }; - let mut ctrl: [u8; CMSG_LEN] = unsafe { mem::uninitialized() }; + let mut ctrl: cmsg::Aligned<[u8; CMSG_LEN]> = + cmsg::Aligned(unsafe { mem::uninitialized() }); let mut hdr = libc::msghdr { msg_name: &mut name as *mut _ as _, msg_namelen: mem::size_of::() as _, msg_iov: &mut iov, msg_iovlen: 1, - msg_control: ctrl.as_mut_ptr() as _, + msg_control: ctrl.0.as_mut_ptr() as _, msg_controllen: CMSG_LEN as _, msg_flags: 0, };