Skip to content

net2 assumes the layout of std::net::SocketAddrV{4,6} matches libc::sockaddr #105

Description

@Thomasdezeeuw

The problem code is here:

net2-rs/src/socket.rs

Lines 87 to 142 in 77a6eb4

fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) {
match *addr {
SocketAddr::V4(ref a) => {
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
}
SocketAddr::V6(ref a) => {
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
}
}
}
fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
match storage.ss_family as c_int {
c::AF_INET => {
unsafe {
assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
let sa = storage as *const _ as *const c::sockaddr_in;
let bits = c::sockaddr_in_u32(&(*sa));
let ip = Ipv4Addr::new((bits >> 24) as u8,
(bits >> 16) as u8,
(bits >> 8) as u8,
bits as u8);
Ok(SocketAddr::V4(SocketAddrV4::new(ip, ::ntoh((*sa).sin_port))))
}
}
c::AF_INET6 => {
unsafe {
assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());
let sa = storage as *const _ as *const c::sockaddr_in6;
#[cfg(windows)] let arr = (*sa).sin6_addr.u.Byte();
#[cfg(not(windows))] let arr = (*sa).sin6_addr.s6_addr;
let ip = Ipv6Addr::new(
(arr[0] as u16) << 8 | (arr[1] as u16),
(arr[2] as u16) << 8 | (arr[3] as u16),
(arr[4] as u16) << 8 | (arr[5] as u16),
(arr[6] as u16) << 8 | (arr[7] as u16),
(arr[8] as u16) << 8 | (arr[9] as u16),
(arr[10] as u16) << 8 | (arr[11] as u16),
(arr[12] as u16) << 8 | (arr[13] as u16),
(arr[14] as u16) << 8 | (arr[15] as u16),
);
#[cfg(windows)] let sin6_scope_id = *(*sa).u.sin6_scope_id();
#[cfg(not(windows))] let sin6_scope_id = (*sa).sin6_scope_id;
Ok(SocketAddr::V6(SocketAddrV6::new(ip,
::ntoh((*sa).sin6_port),
(*sa).sin6_flowinfo,
sin6_scope_id)))
}
}
_ => Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid argument")),
}
}

It assumes that the layout of std::net::SocketAddrV{4,6} matches libc::sockaddr, but this can't be assumed.

Related issues: tokio-rs/mio#1386, rust-lang/socket2#119, rust-lang/rust#78802.

Mio has roughly the same code, this was fixed in tokio-rs/mio#1388, for socket2: rust-lang/socket2#120.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions