From 76b89160fa74a23717e8bc97507397a18dadcc90 Mon Sep 17 00:00:00 2001 From: Max Leonard Inden Date: Tue, 29 Apr 2025 09:58:19 +0200 Subject: [PATCH] fix(udp): zero control message array on fast-apple-datapath `quinn-udp` with fast-apple-datapath previously did not initialize the control message array memory before passing it to `recvmsg_x`. On MacOS 10.15 `recvmsg_x` does not seem to set `msg_controllen`. Thus `CMSG_NXTHDR` reads beyond the control messages written by `recvmsg_x`, into the unitinialized memory region. With this commit, the control message array is initialized (with zeroes) before passing it to `recvmsg_x`, thus no longer reading unset control messages. See https://github.com/quinn-rs/quinn/issues/2214 for details. --- quinn-udp/src/unix.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 _;