diff --git a/quinn-udp/src/unix.rs b/quinn-udp/src/unix.rs index 222523e2d..043a7e316 100644 --- a/quinn-udp/src/unix.rs +++ b/quinn-udp/src/unix.rs @@ -506,7 +506,13 @@ fn recv(io: SockRef<'_>, bufs: &mut [IoSliceMut<'_>], meta: &mut [RecvMeta]) -> #[cfg(apple_fast)] fn recv(io: SockRef<'_>, bufs: &mut [IoSliceMut<'_>], meta: &mut [RecvMeta]) -> io::Result { let mut names = [MaybeUninit::::uninit(); BATCH_SIZE]; - let mut ctrls = [cmsg::Aligned(MaybeUninit::<[u8; CMSG_LEN]>::uninit()); BATCH_SIZE]; + // MacOS 10.15 `recvmsg_x` does not override the `msghdr_x` + // `msg_controllen`. Thus, after the call to `recvmsg_x`, one does not know + // which control messages have been written to. To prevent reading + // uninitialized memory, do not use `MaybeUninit` for `ctrls`, instead + // initialize `ctrls` with `0`s. A control message of all `0`s is + // automatically skipped by `libc::CMSG_NXTHDR`. + let mut ctrls = [cmsg::Aligned([0u8; CMSG_LEN]); BATCH_SIZE]; let mut hdrs = unsafe { mem::zeroed::<[msghdr_x; BATCH_SIZE]>() }; let max_msg_count = bufs.len().min(BATCH_SIZE); for i in 0..max_msg_count { @@ -674,7 +680,7 @@ fn prepare_recv( fn prepare_recv( buf: &mut IoSliceMut, name: &mut MaybeUninit, - ctrl: &mut cmsg::Aligned>, + ctrl: &mut cmsg::Aligned<[u8; CMSG_LEN]>, hdr: &mut msghdr_x, ) { hdr.msg_name = name.as_mut_ptr() as _;