From 5ce3db22487d2d88f035a939abe1131aedbd9d94 Mon Sep 17 00:00:00 2001 From: Kalle Wachsmuth Date: Thu, 7 Mar 2024 16:01:48 +0100 Subject: make `std::os::unix::ucred` module private --- library/std/src/os/unix/mod.rs | 16 ---- library/std/src/os/unix/net/mod.rs | 29 ++++++ library/std/src/os/unix/net/stream.rs | 33 ++----- library/std/src/os/unix/net/ucred.rs | 135 ++++++++++++++++++++++++++++ library/std/src/os/unix/net/ucred/tests.rs | 46 ++++++++++ library/std/src/os/unix/ucred.rs | 137 ----------------------------- library/std/src/os/unix/ucred/tests.rs | 46 ---------- 7 files changed, 219 insertions(+), 223 deletions(-) create mode 100644 library/std/src/os/unix/net/ucred.rs create mode 100644 library/std/src/os/unix/net/ucred/tests.rs delete mode 100644 library/std/src/os/unix/ucred.rs delete mode 100644 library/std/src/os/unix/ucred/tests.rs diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 5ba8719e6ff..b0633fd7bfc 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -95,22 +95,6 @@ pub mod process; pub mod raw; pub mod thread; -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "watchos", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "nto", -))] -pub mod ucred; - /// A prelude for conveniently writing platform-specific code. /// /// Includes all extension traits, and some important type definitions. diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index 6da3e350bf1..28c1188677b 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -12,6 +12,20 @@ mod listener; mod stream; #[cfg(all(test, not(target_os = "emscripten")))] mod tests; +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "nto", +))] +mod ucred; #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::addr::*; @@ -24,3 +38,18 @@ pub use self::datagram::*; pub use self::listener::*; #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::stream::*; +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "nto", +))] +#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] +pub use self::ucred::*; diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index b1cd504e219..069cb299e28 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -1,10 +1,3 @@ -#[cfg(any(doc, target_os = "android", target_os = "linux"))] -use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary}; -use super::{sockaddr_un, SocketAddr}; -use crate::fmt; -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::net::Shutdown; -use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(any( target_os = "android", target_os = "linux", @@ -17,28 +10,20 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned target_os = "netbsd", target_os = "openbsd" ))] -use crate::os::unix::ucred; +use super::{peer_cred, UCred}; +#[cfg(any(doc, target_os = "android", target_os = "linux"))] +use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary}; +use super::{sockaddr_un, SocketAddr}; +use crate::fmt; +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::net::Shutdown; +use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::path::Path; use crate::sys::cvt; use crate::sys::net::Socket; use crate::sys_common::{AsInner, FromInner}; use crate::time::Duration; -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "macos", - target_os = "watchos", - target_os = "netbsd", - target_os = "openbsd" -))] -pub use ucred::UCred; - /// A Unix stream socket. /// /// # Examples @@ -247,7 +232,7 @@ impl UnixStream { target_os = "openbsd" ))] pub fn peer_cred(&self) -> io::Result { - ucred::peer_cred(self) + peer_cred(self) } /// Sets the read timeout for the socket. diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs new file mode 100644 index 00000000000..de09c93840a --- /dev/null +++ b/library/std/src/os/unix/net/ucred.rs @@ -0,0 +1,135 @@ +// NOTE: Code in this file is heavily based on work done in PR 13 from the tokio-uds repository on +// GitHub. +// +// For reference, the link is here: https://github.com/tokio-rs/tokio-uds/pull/13 +// Credit to Martin Habovštiak (GitHub username Kixunil) and contributors for this work. + +use libc::{gid_t, pid_t, uid_t}; + +/// Credentials for a UNIX process for credentials passing. +#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct UCred { + /// The UID part of the peer credential. This is the effective UID of the process at the domain + /// socket's endpoint. + pub uid: uid_t, + /// The GID part of the peer credential. This is the effective GID of the process at the domain + /// socket's endpoint. + pub gid: gid_t, + /// The PID part of the peer credential. This field is optional because the PID part of the + /// peer credentials is not supported on every platform. On platforms where the mechanism to + /// discover the PID exists, this field will be populated to the PID of the process at the + /// domain socket's endpoint. Otherwise, it will be set to None. + pub pid: Option, +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(super) use self::impl_linux::peer_cred; + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd" +))] +pub(super) use self::impl_bsd::peer_cred; + +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +pub(super) use self::impl_mac::peer_cred; + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod impl_linux { + use super::UCred; + use crate::os::unix::io::AsRawFd; + use crate::os::unix::net::UnixStream; + use crate::{io, mem}; + use libc::{c_void, getsockopt, socklen_t, ucred, SOL_SOCKET, SO_PEERCRED}; + + pub fn peer_cred(socket: &UnixStream) -> io::Result { + let ucred_size = mem::size_of::(); + + // Trivial sanity checks. + assert!(mem::size_of::() <= mem::size_of::()); + assert!(ucred_size <= u32::MAX as usize); + + let mut ucred_size = ucred_size as socklen_t; + let mut ucred: ucred = ucred { pid: 1, uid: 1, gid: 1 }; + + unsafe { + let ret = getsockopt( + socket.as_raw_fd(), + SOL_SOCKET, + SO_PEERCRED, + core::ptr::addr_of_mut!(ucred) as *mut c_void, + &mut ucred_size, + ); + + if ret == 0 && ucred_size as usize == mem::size_of::() { + Ok(UCred { uid: ucred.uid, gid: ucred.gid, pid: Some(ucred.pid) }) + } else { + Err(io::Error::last_os_error()) + } + } + } +} + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "nto", +))] +mod impl_bsd { + use super::UCred; + use crate::io; + use crate::os::unix::io::AsRawFd; + use crate::os::unix::net::UnixStream; + + pub fn peer_cred(socket: &UnixStream) -> io::Result { + let mut cred = UCred { uid: 1, gid: 1, pid: None }; + unsafe { + let ret = libc::getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); + + if ret == 0 { Ok(cred) } else { Err(io::Error::last_os_error()) } + } + } +} + +#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] +mod impl_mac { + use super::UCred; + use crate::os::unix::io::AsRawFd; + use crate::os::unix::net::UnixStream; + use crate::{io, mem}; + use libc::{c_void, getpeereid, getsockopt, pid_t, socklen_t, LOCAL_PEERPID, SOL_LOCAL}; + + pub fn peer_cred(socket: &UnixStream) -> io::Result { + let mut cred = UCred { uid: 1, gid: 1, pid: None }; + unsafe { + let ret = getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); + + if ret != 0 { + return Err(io::Error::last_os_error()); + } + + let mut pid: pid_t = 1; + let mut pid_size = mem::size_of::() as socklen_t; + + let ret = getsockopt( + socket.as_raw_fd(), + SOL_LOCAL, + LOCAL_PEERPID, + core::ptr::addr_of_mut!(pid) as *mut c_void, + &mut pid_size, + ); + + if ret == 0 && pid_size as usize == mem::size_of::() { + cred.pid = Some(pid); + Ok(cred) + } else { + Err(io::Error::last_os_error()) + } + } + } +} diff --git a/library/std/src/os/unix/net/ucred/tests.rs b/library/std/src/os/unix/net/ucred/tests.rs new file mode 100644 index 00000000000..dd99ecdd819 --- /dev/null +++ b/library/std/src/os/unix/net/ucred/tests.rs @@ -0,0 +1,46 @@ +use crate::os::unix::net::UnixStream; +use libc::{getegid, geteuid, getpid}; + +#[test] +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "tvos", + target_os = "macos", + target_os = "watchos", + target_os = "openbsd" +))] +fn test_socket_pair() { + // Create two connected sockets and get their peer credentials. They should be equal. + let (sock_a, sock_b) = UnixStream::pair().unwrap(); + let (cred_a, cred_b) = (sock_a.peer_cred().unwrap(), sock_b.peer_cred().unwrap()); + assert_eq!(cred_a, cred_b); + + // Check that the UID and GIDs match up. + let uid = unsafe { geteuid() }; + let gid = unsafe { getegid() }; + assert_eq!(cred_a.uid, uid); + assert_eq!(cred_a.gid, gid); +} + +#[test] +#[cfg(any( + target_os = "linux", + target_os = "ios", + target_os = "macos", + target_os = "watchos", + target_os = "tvos", +))] +fn test_socket_pair_pids(arg: Type) -> RetType { + // Create two connected sockets and get their peer credentials. + let (sock_a, sock_b) = UnixStream::pair().unwrap(); + let (cred_a, cred_b) = (sock_a.peer_cred().unwrap(), sock_b.peer_cred().unwrap()); + + // On supported platforms (see the cfg above), the credentials should always include the PID. + let pid = unsafe { getpid() }; + assert_eq!(cred_a.pid, Some(pid)); + assert_eq!(cred_b.pid, Some(pid)); +} diff --git a/library/std/src/os/unix/ucred.rs b/library/std/src/os/unix/ucred.rs deleted file mode 100644 index 6efa74182cc..00000000000 --- a/library/std/src/os/unix/ucred.rs +++ /dev/null @@ -1,137 +0,0 @@ -//! Unix peer credentials. - -// NOTE: Code in this file is heavily based on work done in PR 13 from the tokio-uds repository on -// GitHub. -// -// For reference, the link is here: https://github.com/tokio-rs/tokio-uds/pull/13 -// Credit to Martin Habovštiak (GitHub username Kixunil) and contributors for this work. - -use libc::{gid_t, pid_t, uid_t}; - -/// Credentials for a UNIX process for credentials passing. -#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub struct UCred { - /// The UID part of the peer credential. This is the effective UID of the process at the domain - /// socket's endpoint. - pub uid: uid_t, - /// The GID part of the peer credential. This is the effective GID of the process at the domain - /// socket's endpoint. - pub gid: gid_t, - /// The PID part of the peer credential. This field is optional because the PID part of the - /// peer credentials is not supported on every platform. On platforms where the mechanism to - /// discover the PID exists, this field will be populated to the PID of the process at the - /// domain socket's endpoint. Otherwise, it will be set to None. - pub pid: Option, -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub use self::impl_linux::peer_cred; - -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd" -))] -pub use self::impl_bsd::peer_cred; - -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] -pub use self::impl_mac::peer_cred; - -#[cfg(any(target_os = "linux", target_os = "android"))] -pub mod impl_linux { - use super::UCred; - use crate::os::unix::io::AsRawFd; - use crate::os::unix::net::UnixStream; - use crate::{io, mem}; - use libc::{c_void, getsockopt, socklen_t, ucred, SOL_SOCKET, SO_PEERCRED}; - - pub fn peer_cred(socket: &UnixStream) -> io::Result { - let ucred_size = mem::size_of::(); - - // Trivial sanity checks. - assert!(mem::size_of::() <= mem::size_of::()); - assert!(ucred_size <= u32::MAX as usize); - - let mut ucred_size = ucred_size as socklen_t; - let mut ucred: ucred = ucred { pid: 1, uid: 1, gid: 1 }; - - unsafe { - let ret = getsockopt( - socket.as_raw_fd(), - SOL_SOCKET, - SO_PEERCRED, - core::ptr::addr_of_mut!(ucred) as *mut c_void, - &mut ucred_size, - ); - - if ret == 0 && ucred_size as usize == mem::size_of::() { - Ok(UCred { uid: ucred.uid, gid: ucred.gid, pid: Some(ucred.pid) }) - } else { - Err(io::Error::last_os_error()) - } - } - } -} - -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "nto", -))] -pub mod impl_bsd { - use super::UCred; - use crate::io; - use crate::os::unix::io::AsRawFd; - use crate::os::unix::net::UnixStream; - - pub fn peer_cred(socket: &UnixStream) -> io::Result { - let mut cred = UCred { uid: 1, gid: 1, pid: None }; - unsafe { - let ret = libc::getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); - - if ret == 0 { Ok(cred) } else { Err(io::Error::last_os_error()) } - } - } -} - -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] -pub mod impl_mac { - use super::UCred; - use crate::os::unix::io::AsRawFd; - use crate::os::unix::net::UnixStream; - use crate::{io, mem}; - use libc::{c_void, getpeereid, getsockopt, pid_t, socklen_t, LOCAL_PEERPID, SOL_LOCAL}; - - pub fn peer_cred(socket: &UnixStream) -> io::Result { - let mut cred = UCred { uid: 1, gid: 1, pid: None }; - unsafe { - let ret = getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); - - if ret != 0 { - return Err(io::Error::last_os_error()); - } - - let mut pid: pid_t = 1; - let mut pid_size = mem::size_of::() as socklen_t; - - let ret = getsockopt( - socket.as_raw_fd(), - SOL_LOCAL, - LOCAL_PEERPID, - core::ptr::addr_of_mut!(pid) as *mut c_void, - &mut pid_size, - ); - - if ret == 0 && pid_size as usize == mem::size_of::() { - cred.pid = Some(pid); - Ok(cred) - } else { - Err(io::Error::last_os_error()) - } - } - } -} diff --git a/library/std/src/os/unix/ucred/tests.rs b/library/std/src/os/unix/ucred/tests.rs deleted file mode 100644 index dd99ecdd819..00000000000 --- a/library/std/src/os/unix/ucred/tests.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::os::unix::net::UnixStream; -use libc::{getegid, geteuid, getpid}; - -#[test] -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "tvos", - target_os = "macos", - target_os = "watchos", - target_os = "openbsd" -))] -fn test_socket_pair() { - // Create two connected sockets and get their peer credentials. They should be equal. - let (sock_a, sock_b) = UnixStream::pair().unwrap(); - let (cred_a, cred_b) = (sock_a.peer_cred().unwrap(), sock_b.peer_cred().unwrap()); - assert_eq!(cred_a, cred_b); - - // Check that the UID and GIDs match up. - let uid = unsafe { geteuid() }; - let gid = unsafe { getegid() }; - assert_eq!(cred_a.uid, uid); - assert_eq!(cred_a.gid, gid); -} - -#[test] -#[cfg(any( - target_os = "linux", - target_os = "ios", - target_os = "macos", - target_os = "watchos", - target_os = "tvos", -))] -fn test_socket_pair_pids(arg: Type) -> RetType { - // Create two connected sockets and get their peer credentials. - let (sock_a, sock_b) = UnixStream::pair().unwrap(); - let (cred_a, cred_b) = (sock_a.peer_cred().unwrap(), sock_b.peer_cred().unwrap()); - - // On supported platforms (see the cfg above), the credentials should always include the PID. - let pid = unsafe { getpid() }; - assert_eq!(cred_a.pid, Some(pid)); - assert_eq!(cred_b.pid, Some(pid)); -} -- cgit 1.4.1-3-g733a5