mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-29 00:00:11 +02:00
net: implement UCred::pid on FreeBSD (#8086)
This commit is contained in:
+8
-1
@@ -1,4 +1,4 @@
|
|||||||
316
|
323
|
||||||
&
|
&
|
||||||
+
|
+
|
||||||
<
|
<
|
||||||
@@ -189,14 +189,17 @@ mutex
|
|||||||
Mutex
|
Mutex
|
||||||
Nagle
|
Nagle
|
||||||
namespace
|
namespace
|
||||||
|
NetBSD
|
||||||
nonblocking
|
nonblocking
|
||||||
nondecreasing
|
nondecreasing
|
||||||
noop
|
noop
|
||||||
ntasks
|
ntasks
|
||||||
|
NTO
|
||||||
NUMA
|
NUMA
|
||||||
ok
|
ok
|
||||||
oneshot
|
oneshot
|
||||||
opcode
|
opcode
|
||||||
|
OpenBSD
|
||||||
ORed
|
ORed
|
||||||
os
|
os
|
||||||
parker
|
parker
|
||||||
@@ -213,6 +216,7 @@ RAII
|
|||||||
RCU
|
RCU
|
||||||
reallocations
|
reallocations
|
||||||
recv's
|
recv's
|
||||||
|
Redox
|
||||||
refactors
|
refactors
|
||||||
refcount
|
refcount
|
||||||
refcounting
|
refcounting
|
||||||
@@ -279,6 +283,7 @@ tokio's
|
|||||||
Tokio's
|
Tokio's
|
||||||
tuple
|
tuple
|
||||||
Tuple
|
Tuple
|
||||||
|
tvOS
|
||||||
tx
|
tx
|
||||||
udp
|
udp
|
||||||
UDP
|
UDP
|
||||||
@@ -306,6 +311,7 @@ vec
|
|||||||
versa
|
versa
|
||||||
versioned
|
versioned
|
||||||
versioning
|
versioning
|
||||||
|
visionOS
|
||||||
vtable
|
vtable
|
||||||
waker
|
waker
|
||||||
wakers
|
wakers
|
||||||
@@ -313,5 +319,6 @@ Wakers
|
|||||||
wakeup
|
wakeup
|
||||||
wakeups
|
wakeups
|
||||||
WASI
|
WASI
|
||||||
|
watchOS
|
||||||
workstealing
|
workstealing
|
||||||
ZST
|
ZST
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ impl UCred {
|
|||||||
|
|
||||||
/// Gets PID (process ID) of the process.
|
/// Gets PID (process ID) of the process.
|
||||||
///
|
///
|
||||||
/// This is only implemented under Linux, Android, iOS, macOS, Solaris,
|
/// This is implemented under Linux, Android, OpenBSD, FreeBSD (since
|
||||||
/// Illumos and Cygwin. On other platforms this will always return `None`.
|
/// FreeBSD 13), NetBSD, NTO, iOS, macOS, tvOS, watchOS, visionOS,
|
||||||
|
/// Solaris, Illumos, Cygwin, Haiku, and Redox. On other platforms this
|
||||||
|
/// will always return `None`.
|
||||||
pub fn pid(&self) -> Option<unix::pid_t> {
|
pub fn pid(&self) -> Option<unix::pid_t> {
|
||||||
self.pid
|
self.pid
|
||||||
}
|
}
|
||||||
@@ -44,8 +46,11 @@ pub(crate) use self::impl_linux::get_peer_cred;
|
|||||||
#[cfg(any(target_os = "netbsd", target_os = "nto"))]
|
#[cfg(any(target_os = "netbsd", target_os = "nto"))]
|
||||||
pub(crate) use self::impl_netbsd::get_peer_cred;
|
pub(crate) use self::impl_netbsd::get_peer_cred;
|
||||||
|
|
||||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
|
#[cfg(target_os = "dragonfly")]
|
||||||
pub(crate) use self::impl_bsd::get_peer_cred;
|
pub(crate) use self::impl_dragonfly::get_peer_cred;
|
||||||
|
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
pub(crate) use self::impl_freebsd::get_peer_cred;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
@@ -172,8 +177,8 @@ pub(crate) mod impl_netbsd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
|
#[cfg(target_os = "dragonfly")]
|
||||||
pub(crate) mod impl_bsd {
|
pub(crate) mod impl_dragonfly {
|
||||||
use crate::net::unix::{self, UnixStream};
|
use crate::net::unix::{self, UnixStream};
|
||||||
|
|
||||||
use libc::getpeereid;
|
use libc::getpeereid;
|
||||||
@@ -203,6 +208,74 @@ pub(crate) mod impl_bsd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
pub(crate) mod impl_freebsd {
|
||||||
|
use crate::net::unix::{self, UnixStream};
|
||||||
|
|
||||||
|
use libc::{c_void, getsockopt, socklen_t, xucred, LOCAL_PEERCRED, XUCRED_VERSION};
|
||||||
|
use std::io;
|
||||||
|
use std::mem::{size_of, MaybeUninit};
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
pub(crate) fn get_peer_cred(sock: &UnixStream) -> io::Result<super::UCred> {
|
||||||
|
// `SOL_LOCAL` is not re-exported by `libc` for FreeBSD; it is defined
|
||||||
|
// as 0 in `<sys/un.h>`.
|
||||||
|
const SOL_LOCAL: libc::c_int = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let raw_fd = sock.as_raw_fd();
|
||||||
|
|
||||||
|
let mut xucred = MaybeUninit::<xucred>::zeroed();
|
||||||
|
let mut len = size_of::<xucred>() as socklen_t;
|
||||||
|
|
||||||
|
let ret = getsockopt(
|
||||||
|
raw_fd,
|
||||||
|
SOL_LOCAL,
|
||||||
|
LOCAL_PEERCRED,
|
||||||
|
xucred.as_mut_ptr() as *mut c_void,
|
||||||
|
&mut len,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ret != 0 {
|
||||||
|
return Err(io::Error::last_os_error());
|
||||||
|
}
|
||||||
|
if len as usize != size_of::<xucred>() {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
"unexpected xucred size from LOCAL_PEERCRED",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let xucred = xucred.assume_init();
|
||||||
|
|
||||||
|
// Match `getpeereid(3)` and reject any `xucred` whose version we
|
||||||
|
// don't know how to interpret.
|
||||||
|
if xucred.cr_version != XUCRED_VERSION {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
"unexpected xucred version from LOCAL_PEERCRED",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// `cr_pid` is populated by the kernel since FreeBSD 13. PID 0 is
|
||||||
|
// the kernel scheduler and never a real userland peer, so we
|
||||||
|
// surface it as `None` rather than a misleading `Some(0)`.
|
||||||
|
let pid = match xucred.cr_pid__c_anonymous_union.cr_pid {
|
||||||
|
0 => None,
|
||||||
|
p => Some(p as unix::pid_t),
|
||||||
|
};
|
||||||
|
|
||||||
|
// `xucred` carries the effective uid in `cr_uid` and the effective
|
||||||
|
// gid in `cr_groups[0]`, matching what `getpeereid(2)` returns.
|
||||||
|
Ok(super::UCred {
|
||||||
|
uid: xucred.cr_uid as unix::uid_t,
|
||||||
|
gid: xucred.cr_groups[0] as unix::gid_t,
|
||||||
|
pid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "ios",
|
target_os = "ios",
|
||||||
|
|||||||
@@ -23,4 +23,35 @@ async fn test_socket_pair() {
|
|||||||
|
|
||||||
assert_eq!(cred_a.uid(), uid);
|
assert_eq!(cred_a.uid(), uid);
|
||||||
assert_eq!(cred_a.gid(), gid);
|
assert_eq!(cred_a.gid(), gid);
|
||||||
|
|
||||||
|
// On platforms where `UCred::pid` is implemented and the kernel
|
||||||
|
// populates it, both ends of a `socketpair` must report the current
|
||||||
|
// process's PID.
|
||||||
|
//
|
||||||
|
// FreeBSD COMPAT32 (32-bit binary on a 64-bit kernel) leaves `cr_pid`
|
||||||
|
// zeroed pending FreeBSD bug 294833; the assertion is gated on 64-bit
|
||||||
|
// FreeBSD until that fix ships.
|
||||||
|
#[cfg(any(
|
||||||
|
target_os = "linux",
|
||||||
|
target_os = "android",
|
||||||
|
target_os = "openbsd",
|
||||||
|
all(target_os = "freebsd", target_pointer_width = "64"),
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "nto",
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios",
|
||||||
|
target_os = "tvos",
|
||||||
|
target_os = "watchos",
|
||||||
|
target_os = "visionos",
|
||||||
|
target_os = "solaris",
|
||||||
|
target_os = "illumos",
|
||||||
|
target_os = "redox",
|
||||||
|
target_os = "haiku",
|
||||||
|
target_os = "cygwin",
|
||||||
|
))]
|
||||||
|
{
|
||||||
|
let pid = unsafe { libc::getpid() };
|
||||||
|
assert_eq!(cred_a.pid(), Some(pid));
|
||||||
|
assert_eq!(cred_b.pid(), Some(pid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user