Skip to content

Commit

Permalink
making sure that sa_family is always initialized
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan561 committed Dec 1, 2023
1 parent e13a182 commit e25f7e4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
19 changes: 8 additions & 11 deletions src/sys/socket/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ impl fmt::Display for SocketAddressLengthNotDynamic {
impl std::error::Error for SocketAddressLengthNotDynamic {}

impl private::SockaddrLikePriv for () {
fn as_mut_ptr(&mut self) -> *mut libc::sockaddr {
fn as_mut_ptr(_: &mut std::mem::MaybeUninit<Self>) -> *mut libc::sockaddr {
ptr::null_mut()
}
}
Expand Down Expand Up @@ -1451,16 +1451,13 @@ impl PartialEq for SockaddrStorage {

pub(super) mod private {
pub trait SockaddrLikePriv {
/// Returns a mutable raw pointer to the inner structure.
///
/// # Safety
///
/// This method is technically safe, but modifying the inner structure's
/// `family` or `len` fields may result in violating Nix's invariants.
/// It is best to use this method only with foreign functions that do
/// not change the sockaddr type.
fn as_mut_ptr(&mut self) -> *mut libc::sockaddr {
self as *mut Self as *mut libc::sockaddr
fn as_mut_ptr(
s: &mut std::mem::MaybeUninit<Self>,
) -> *mut libc::sockaddr
where
Self: Sized,
{
s.as_mut_ptr().cast()
}
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1627,12 +1627,12 @@ impl<S> MultiHeaders<S> {
let items = addresses
.iter_mut()
.enumerate()
.map(|(ix, address)| {
.map(|(ix, mut address)| {
let (ptr, cap) = match &mut cmsg_buffers {
Some(v) => ((&mut v[ix * msg_controllen] as *mut u8), msg_controllen),
None => (std::ptr::null_mut(), 0),
};
let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null_mut(), 0, ptr, cap, address.as_mut_ptr()) };
let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null_mut(), 0, ptr, cap, &mut address) };
libc::mmsghdr {
msg_hdr,
msg_len: 0,
Expand Down Expand Up @@ -1962,17 +1962,25 @@ unsafe fn pack_mhdr_to_receive<S>(
iov_buffer_len: usize,
cmsg_buffer: *mut u8,
cmsg_capacity: usize,
address: *mut S,
address: &mut mem::MaybeUninit<S>,
) -> msghdr
where
S: SockaddrLike
{
let addr_ptr = S::as_mut_ptr(address);

if !addr_ptr.is_null() {
unsafe {
std::ptr::addr_of_mut!((*addr_ptr).sa_family).write(libc::AF_UNSPEC as _);
}
}

// Musl's msghdr has private fields, so this is the only way to
// initialize it.
let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
let p = mhdr.as_mut_ptr();
unsafe {
(*p).msg_name = address as *mut c_void;
(*p).msg_name = addr_ptr.cast();
(*p).msg_namelen = S::size();
(*p).msg_iov = iov_buffer as *mut iovec;
(*p).msg_iovlen = iov_buffer_len as _;
Expand Down Expand Up @@ -2062,7 +2070,7 @@ pub fn recvmsg<'a, 'outer, 'inner, S>(fd: RawFd, iov: &'outer mut [IoSliceMut<'i
.map(|v| (v.as_mut_ptr(), v.capacity()))
.unwrap_or((ptr::null_mut(), 0));
let mut mhdr = unsafe {
pack_mhdr_to_receive(iov.as_mut().as_mut_ptr(), iov.len(), msg_control, msg_controllen, address.as_mut_ptr())
pack_mhdr_to_receive(iov.as_mut().as_mut_ptr(), iov.len(), msg_control, msg_controllen, &mut address)
};

let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) };
Expand Down

0 comments on commit e25f7e4

Please sign in to comment.