From fe1d97b559a3056eff1db93b584a07783ae60dbc Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 26 Nov 2023 21:12:43 -0800 Subject: [PATCH 1/5] OpenBSD fix long socket addresses There is an OpenBSD bug where the "len" returned by functions like "getsockname" is too long and makes it so the resulting address contains zero bytes. While this isn't a problem for C code, where strings are null terminated anyways, it's a problem for Rust. This commit fixes this issue by adding a check that truncates the address length to the first zero when OpenBSD is detected. If there are no zeroes, it just uses the original length provided by the system. Signed-off-by: John Nunley --- library/std/src/os/unix/net/addr.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 6c99e8c36203a..02a9fbd52542e 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -111,7 +111,17 @@ impl SocketAddr { // When there is a datagram from unnamed unix socket // linux returns zero bytes of address len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address - } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { + } else if cfg!(target_os = "openbsd") { + // OpenBSD has a bug where the socket name's length + // is more than what the buffer actually contains. + // Figure out the length for ourselves. + // https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2 + let sun_path: &[u8] = unsafe { crate::mem::transmute::<&[i8], &[u8]>(&addr.sun_path) }; + len = crate::sys::memchr::memchr(0, sun_path) + .map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t); + } + + if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { return Err(io::const_io_error!( io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket", From da6b4f6fb9c2b06748ec94070c51ed6d438ef14e Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 1 Dec 2023 17:30:42 -0800 Subject: [PATCH 2/5] bug -> feature Signed-off-by: John Nunley --- library/std/src/os/unix/net/addr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 02a9fbd52542e..d0dacb4c50f32 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -112,9 +112,9 @@ impl SocketAddr { // linux returns zero bytes of address len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address } else if cfg!(target_os = "openbsd") { - // OpenBSD has a bug where the socket name's length - // is more than what the buffer actually contains. - // Figure out the length for ourselves. + // OpenBSD implements getsockname in a way where the + // socket name's length is more than what the buffer + // actually contains. Figure out the length for ourselves. // https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2 let sun_path: &[u8] = unsafe { crate::mem::transmute::<&[i8], &[u8]>(&addr.sun_path) }; len = crate::sys::memchr::memchr(0, sun_path) From d1090cf5fcf63449a27b8240fc7c6ed93dd781e0 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 18 Feb 2024 12:07:43 -0800 Subject: [PATCH 3/5] chore: Review comments Signed-off-by: John Nunley --- library/std/src/os/unix/net/addr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index d0dacb4c50f32..079f80fe3d21f 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -116,12 +116,12 @@ impl SocketAddr { // socket name's length is more than what the buffer // actually contains. Figure out the length for ourselves. // https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2 - let sun_path: &[u8] = unsafe { crate::mem::transmute::<&[i8], &[u8]>(&addr.sun_path) }; + let sun_path: &[u8] = unsafe { crate::mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) }; len = crate::sys::memchr::memchr(0, sun_path) .map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t); } - if addr.sun_family != libc::AF_UNIX as libc::sa_family_t { + if len != 0 && addr.sun_family != libc::AF_UNIX as libc::sa_family_t { return Err(io::const_io_error!( io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket", From 731b456ab2587015a28792ee1a44ea87334626b5 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 18 Feb 2024 12:53:48 -0800 Subject: [PATCH 4/5] chore: Fix tidy Signed-off-by: John Nunley --- library/std/src/os/unix/net/addr.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 079f80fe3d21f..22dedd9fd31ec 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -112,11 +112,12 @@ impl SocketAddr { // linux returns zero bytes of address len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address } else if cfg!(target_os = "openbsd") { - // OpenBSD implements getsockname in a way where the + // OpenBSD implements getsockname in a way where the // socket name's length is more than what the buffer // actually contains. Figure out the length for ourselves. // https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2 - let sun_path: &[u8] = unsafe { crate::mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) }; + let sun_path: &[u8] = + unsafe { crate::mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) }; len = crate::sys::memchr::memchr(0, sun_path) .map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t); } From b7eebfafd2b56f723058008af2d7abf8936077a4 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 18 Feb 2024 13:15:10 -0800 Subject: [PATCH 5/5] chore: Fix binary operation Signed-off-by: John Nunley --- library/std/src/os/unix/net/addr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 22dedd9fd31ec..5de9412c1aa49 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -122,7 +122,7 @@ impl SocketAddr { .map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t); } - if len != 0 && addr.sun_family != libc::AF_UNIX as libc::sa_family_t { + if len == 0 && addr.sun_family != libc::AF_UNIX as libc::sa_family_t { return Err(io::const_io_error!( io::ErrorKind::InvalidInput, "file descriptor did not correspond to a Unix socket",