Skip to content

Commit 5fe8266

Browse files
authored
initialize msg_name with null pointer when msg_name is empty (#2530)
* Use as_mut_ptr() to initialize msg_name in pack_mhdr_to_receive The msg_name field points to a caller-allocated buffer that is used to return the source address if the socket is unconnected. The caller should set msg_namelen to the size of this buffer before this call; upon return from a successful call, msg_namelen will contain the length of the returned address. If the application does not need to know the source address, msg_name can be specified as NULL. In case we use () msgname_len gets initialized with 0, but a dangling pointer to the array with msg_name. This works for the first iteration somehow, but after that kernel sets msgname_len to a non-zero and second invocation with the same MultiHeader fails Fixes #2506 * CI doesn't check for rustfmt but I'm tired of picking stuff
1 parent a41a1f0 commit 5fe8266

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/sys/socket/mod.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,20 @@ pub use self::addr::{SockaddrLike, SockaddrStorage};
3939
pub use self::addr::{AddressFamily, UnixAddr};
4040
#[cfg(not(solarish))]
4141
pub use self::addr::{AddressFamily, UnixAddr};
42-
#[cfg(not(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox")))]
42+
#[cfg(not(any(
43+
solarish,
44+
target_os = "haiku",
45+
target_os = "hurd",
46+
target_os = "redox"
47+
)))]
4348
#[cfg(feature = "net")]
4449
pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6};
45-
#[cfg(any(solarish, target_os = "haiku", target_os = "hurd", target_os = "redox"))]
50+
#[cfg(any(
51+
solarish,
52+
target_os = "haiku",
53+
target_os = "hurd",
54+
target_os = "redox"
55+
))]
4656
#[cfg(feature = "net")]
4757
pub use self::addr::{SockaddrIn, SockaddrIn6};
4858

@@ -851,17 +861,17 @@ pub enum ControlMessageOwned {
851861
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
852862
Ipv6HopLimit(i32),
853863

854-
/// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
864+
/// Retrieve the DSCP (ToS) header field of the incoming IPv4 packet.
855865
#[cfg(any(linux_android, target_os = "freebsd"))]
856866
#[cfg(feature = "net")]
857867
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
858868
Ipv4Tos(u8),
859869

860-
/// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet.
870+
/// Retrieve the DSCP (Traffic Class) header field of the incoming IPv6 packet.
861871
#[cfg(any(linux_android, target_os = "freebsd"))]
862872
#[cfg(feature = "net")]
863873
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
864-
Ipv6TClass(i32),
874+
Ipv6TClass(i32),
865875

866876
/// UDP Generic Receive Offload (GRO) allows receiving multiple UDP
867877
/// packets from a single sender.
@@ -1119,7 +1129,7 @@ impl ControlMessageOwned {
11191129
(_, _) => {
11201130
let sl = unsafe { std::slice::from_raw_parts(p, len) };
11211131
let ucmsg = UnknownCmsg {
1122-
cmsg_header: *header,
1132+
cmsg_header: *header,
11231133
data_bytes: Vec::<u8>::from(sl),
11241134
};
11251135
ControlMessageOwned::Unknown(ucmsg)
@@ -2059,7 +2069,10 @@ unsafe fn pack_mhdr_to_receive<S>(
20592069
let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
20602070
let p = mhdr.as_mut_ptr();
20612071
unsafe {
2062-
(*p).msg_name = address as *mut c_void;
2072+
// it is important to use as_mut_ptr() here since S can be
2073+
// a zero sized type representing by a dangling pointer.
2074+
// as_mut_ptr() handles this case and uses a null pointer instead
2075+
(*p).msg_name = (*address).as_mut_ptr() as *mut c_void;
20632076
(*p).msg_namelen = S::size();
20642077
(*p).msg_iov = iov_buffer as *mut iovec;
20652078
(*p).msg_iovlen = iov_buffer_len as _;
@@ -2517,4 +2530,3 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
25172530
Errno::result(shutdown(df, how)).map(drop)
25182531
}
25192532
}
2520-

0 commit comments

Comments
 (0)