From ef24de24a82fe681581cc130f342363c47c0969a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 7 Jun 2024 07:48:48 +0200 Subject: Merging upstream version 1.75.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rustix/src/backend/linux_raw/c.rs | 128 ++- vendor/rustix/src/backend/linux_raw/conv.rs | 15 +- vendor/rustix/src/backend/linux_raw/event/epoll.rs | 20 +- vendor/rustix/src/backend/linux_raw/event/mod.rs | 1 - .../rustix/src/backend/linux_raw/event/poll_fd.rs | 2 +- .../rustix/src/backend/linux_raw/event/syscalls.rs | 20 +- vendor/rustix/src/backend/linux_raw/event/types.rs | 2 +- vendor/rustix/src/backend/linux_raw/fs/dir.rs | 95 ++- vendor/rustix/src/backend/linux_raw/fs/inotify.rs | 17 +- vendor/rustix/src/backend/linux_raw/fs/syscalls.rs | 8 +- vendor/rustix/src/backend/linux_raw/fs/types.rs | 26 +- vendor/rustix/src/backend/linux_raw/io/errno.rs | 2 +- vendor/rustix/src/backend/linux_raw/io/syscalls.rs | 74 +- vendor/rustix/src/backend/linux_raw/io/types.rs | 6 +- vendor/rustix/src/backend/linux_raw/mm/syscalls.rs | 29 + vendor/rustix/src/backend/linux_raw/mm/types.rs | 52 +- vendor/rustix/src/backend/linux_raw/mod.rs | 2 + vendor/rustix/src/backend/linux_raw/mount/types.rs | 20 +- vendor/rustix/src/backend/linux_raw/net/mod.rs | 1 + vendor/rustix/src/backend/linux_raw/net/msghdr.rs | 2 +- .../src/backend/linux_raw/net/read_sockaddr.rs | 6 +- .../rustix/src/backend/linux_raw/net/send_recv.rs | 10 +- vendor/rustix/src/backend/linux_raw/net/sockopt.rs | 879 +++++++++++++++++++++ .../rustix/src/backend/linux_raw/net/syscalls.rs | 640 +-------------- .../src/backend/linux_raw/net/write_sockaddr.rs | 4 +- vendor/rustix/src/backend/linux_raw/param/auxv.rs | 61 +- vendor/rustix/src/backend/linux_raw/param/init.rs | 14 +- .../src/backend/linux_raw/param/libc_auxv.rs | 12 +- vendor/rustix/src/backend/linux_raw/pipe/types.rs | 4 +- .../src/backend/linux_raw/process/syscalls.rs | 27 +- vendor/rustix/src/backend/linux_raw/rand/types.rs | 2 +- vendor/rustix/src/backend/linux_raw/reg.rs | 12 +- .../src/backend/linux_raw/runtime/syscalls.rs | 10 +- vendor/rustix/src/backend/linux_raw/runtime/tls.rs | 24 +- vendor/rustix/src/backend/linux_raw/shm/mod.rs | 2 + .../rustix/src/backend/linux_raw/shm/syscalls.rs | 47 ++ vendor/rustix/src/backend/linux_raw/shm/types.rs | 30 + .../src/backend/linux_raw/system/syscalls.rs | 17 +- .../src/backend/linux_raw/termios/syscalls.rs | 42 +- vendor/rustix/src/backend/linux_raw/time/types.rs | 4 +- vendor/rustix/src/backend/linux_raw/vdso.rs | 18 +- .../rustix/src/backend/linux_raw/vdso_wrappers.rs | 40 +- 42 files changed, 1584 insertions(+), 843 deletions(-) create mode 100644 vendor/rustix/src/backend/linux_raw/net/sockopt.rs create mode 100644 vendor/rustix/src/backend/linux_raw/shm/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/shm/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/shm/types.rs (limited to 'vendor/rustix/src/backend/linux_raw') diff --git a/vendor/rustix/src/backend/linux_raw/c.rs b/vendor/rustix/src/backend/linux_raw/c.rs index 65ddb1466..01c5eafb1 100644 --- a/vendor/rustix/src/backend/linux_raw/c.rs +++ b/vendor/rustix/src/backend/linux_raw/c.rs @@ -6,7 +6,7 @@ #![allow(unused_imports)] #![allow(non_camel_case_types)] -pub type size_t = usize; +pub(crate) type size_t = usize; pub(crate) use linux_raw_sys::ctypes::*; pub(crate) use linux_raw_sys::errno::EINVAL; pub(crate) use linux_raw_sys::ioctl::{FIONBIO, FIONREAD}; @@ -51,31 +51,88 @@ pub(crate) use linux_raw_sys::{ general::{O_CLOEXEC as SOCK_CLOEXEC, O_NONBLOCK as SOCK_NONBLOCK}, if_ether::*, net::{ - AF_DECnet, __kernel_sa_family_t as sa_family_t, - __kernel_sockaddr_storage as sockaddr_storage, cmsghdr, in6_addr, in_addr, ip_mreq, - ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, - AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, - AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, - AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, - AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, IPPROTO_AH, - IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, IPPROTO_ESP, - IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, IPPROTO_IDP, - IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, IPPROTO_MPLS, - IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, IPPROTO_ROUTING, - IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, IPPROTO_UDPLITE, - IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, - IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, - IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, - MSG_EOR, MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, - SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, - SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE, - SO_LINGER, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, - SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, - SO_SNDTIMEO_OLD, SO_TYPE, TCP_NODELAY, + linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, AF_DECnet, + __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, + cmsghdr, in6_addr, in_addr, ip_mreq, ip_mreq_source, ip_mreqn, ipv6_mreq, AF_APPLETALK, + AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, AF_ECONET, + AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, AF_LLC, + AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, + AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, + IP6T_SO_ORIGINAL_DST, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_MH, IPPROTO_ROUTING, + IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_FREEBIND, IPV6_MULTICAST_HOPS, + IPV6_MULTICAST_LOOP, IPV6_RECVTCLASS, IPV6_TCLASS, IPV6_UNICAST_HOPS, IPV6_V6ONLY, + IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, + IP_FREEBIND, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_RECVTOS, IP_TOS, IP_TTL, + MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_ERRQUEUE, + MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, SCM_CREDENTIALS, + SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, + SOCK_STREAM, SOL_SOCKET, SO_ACCEPTCONN, SO_BROADCAST, SO_COOKIE, SO_DOMAIN, SO_ERROR, + SO_INCOMING_CPU, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_ORIGINAL_DST, SO_PASSCRED, + SO_PROTOCOL, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, + SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, + SO_SNDTIMEO_OLD, SO_TYPE, TCP_CONGESTION, TCP_CORK, TCP_KEEPCNT, TCP_KEEPIDLE, + TCP_KEEPINTVL, TCP_NODELAY, TCP_QUICKACK, TCP_THIN_LINEAR_TIMEOUTS, TCP_USER_TIMEOUT, }, netlink::*, }; +// Cast away bindgen's `enum` type to make these consistent with the other +// `setsockopt`/`getsockopt` level values. +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IP: u32 = linux_raw_sys::net::IPPROTO_IP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ICMP: u32 = linux_raw_sys::net::IPPROTO_ICMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IGMP: u32 = linux_raw_sys::net::IPPROTO_IGMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IPIP: u32 = linux_raw_sys::net::IPPROTO_IPIP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_TCP: u32 = linux_raw_sys::net::IPPROTO_TCP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_EGP: u32 = linux_raw_sys::net::IPPROTO_EGP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_PUP: u32 = linux_raw_sys::net::IPPROTO_PUP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_UDP: u32 = linux_raw_sys::net::IPPROTO_UDP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IDP: u32 = linux_raw_sys::net::IPPROTO_IDP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_TP: u32 = linux_raw_sys::net::IPPROTO_TP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_DCCP: u32 = linux_raw_sys::net::IPPROTO_DCCP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_IPV6: u32 = linux_raw_sys::net::IPPROTO_IPV6 as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_RSVP: u32 = linux_raw_sys::net::IPPROTO_RSVP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_GRE: u32 = linux_raw_sys::net::IPPROTO_GRE as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ESP: u32 = linux_raw_sys::net::IPPROTO_ESP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_AH: u32 = linux_raw_sys::net::IPPROTO_AH as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MTP: u32 = linux_raw_sys::net::IPPROTO_MTP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_BEETPH: u32 = linux_raw_sys::net::IPPROTO_BEETPH as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ENCAP: u32 = linux_raw_sys::net::IPPROTO_ENCAP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_PIM: u32 = linux_raw_sys::net::IPPROTO_PIM as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_COMP: u32 = linux_raw_sys::net::IPPROTO_COMP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_SCTP: u32 = linux_raw_sys::net::IPPROTO_SCTP as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_UDPLITE: u32 = linux_raw_sys::net::IPPROTO_UDPLITE as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MPLS: u32 = linux_raw_sys::net::IPPROTO_MPLS as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_ETHERNET: u32 = linux_raw_sys::net::IPPROTO_ETHERNET as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_RAW: u32 = linux_raw_sys::net::IPPROTO_RAW as _; +#[cfg(feature = "net")] +pub(crate) const IPPROTO_MPTCP: u32 = linux_raw_sys::net::IPPROTO_MPTCP as _; + #[cfg(any(feature = "process", feature = "runtime"))] pub(crate) use linux_raw_sys::general::siginfo_t; @@ -90,7 +147,7 @@ pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + linux_raw_sys::general::SI pub(crate) use linux_raw_sys::{ general::{ CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, - O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PID, P_PIDFD, + O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PGID, P_PID, P_PIDFD, }, ioctl::TIOCSCTTY, }; @@ -209,3 +266,28 @@ pub(crate) const CLOCK_THREAD_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID as _; pub(crate) const CLOCK_PROCESS_CPUTIME_ID: c_int = linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID as _; + +#[cfg(feature = "system")] +mod reboot_symbols { + use super::c_int; + + pub(crate) const LINUX_REBOOT_MAGIC1: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC1 as _; + pub(crate) const LINUX_REBOOT_MAGIC2: c_int = linux_raw_sys::general::LINUX_REBOOT_MAGIC2 as _; + + pub(crate) const LINUX_REBOOT_CMD_RESTART: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_RESTART as _; + pub(crate) const LINUX_REBOOT_CMD_HALT: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_HALT as _; + pub(crate) const LINUX_REBOOT_CMD_CAD_ON: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_ON as _; + pub(crate) const LINUX_REBOOT_CMD_CAD_OFF: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_CAD_OFF as _; + pub(crate) const LINUX_REBOOT_CMD_POWER_OFF: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_POWER_OFF as _; + pub(crate) const LINUX_REBOOT_CMD_SW_SUSPEND: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_SW_SUSPEND as _; + pub(crate) const LINUX_REBOOT_CMD_KEXEC: c_int = + linux_raw_sys::general::LINUX_REBOOT_CMD_KEXEC as _; +} +#[cfg(feature = "system")] +pub(crate) use reboot_symbols::*; diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs index f915db140..4b3c15d7a 100644 --- a/vendor/rustix/src/backend/linux_raw/conv.rs +++ b/vendor/rustix/src/backend/linux_raw/conv.rs @@ -2,8 +2,8 @@ //! //! System call arguments and return values are all communicated with inline //! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping -//! or being accidentally misused as they travel through the code, we wrap -//! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From` +//! or being accidentally misused as they travel through the code, we wrap them +//! in [`ArgReg`] and [`RetReg`] structs. This file provides `From` //! implementations and explicit conversion functions for converting values //! into and out of these wrapper structs. //! @@ -581,7 +581,7 @@ impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { } } -#[cfg(all(feature = "alloc", feature = "event"))] +#[cfg(feature = "event")] impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { #[inline] fn from(flags: crate::event::epoll::CreateFlags) -> Self { @@ -621,6 +621,15 @@ impl<'a, Num: ArgNumber> From for ArgReg< } } +#[cfg(feature = "mm")] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MlockAllFlags) -> Self { + c_uint(flags.bits()) + } +} + #[cfg(feature = "mm")] impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { #[inline] diff --git a/vendor/rustix/src/backend/linux_raw/event/epoll.rs b/vendor/rustix/src/backend/linux_raw/event/epoll.rs index ecd48b784..6aa84d7aa 100644 --- a/vendor/rustix/src/backend/linux_raw/event/epoll.rs +++ b/vendor/rustix/src/backend/linux_raw/event/epoll.rs @@ -1,8 +1,4 @@ -//! epoll support. -//! -//! This is an experiment, and it isn't yet clear whether epoll is the right -//! level of abstraction at which to introduce safety. But it works fairly well -//! in simple examples 🙂. +//! Linx `epoll` support. //! //! # Examples //! @@ -79,6 +75,7 @@ use crate::backend::c; use crate::backend::event::syscalls; use crate::fd::{AsFd, AsRawFd, OwnedFd}; use crate::io; +#[cfg(feature = "alloc")] use alloc::vec::Vec; use bitflags::bitflags; use core::ffi::c_void; @@ -93,7 +90,7 @@ bitflags! { /// `EPOLL_CLOEXEC` const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; - /// + /// const _ = !0; } } @@ -148,7 +145,7 @@ bitflags! { /// `EPOLLEXCLUSIVE` const EXCLUSIVE = linux_raw_sys::general::EPOLLEXCLUSIVE as u32; - /// + /// const _ = !0; } } @@ -242,6 +239,8 @@ pub fn delete(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { /// /// For each event of interest, an element is written to `events`. On /// success, this returns the number of written elements. +#[cfg(feature = "alloc")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] #[inline] pub fn wait(epoll: impl AsFd, event_list: &mut EventVec, timeout: c::c_int) -> io::Result<()> { // SAFETY: We're calling `epoll_wait` via FFI and we know how it @@ -288,8 +287,8 @@ pub struct Event { pub data: EventData, } -/// Data assocated with an [`Event`]. This can either be a 64-bit integer value -/// or a pointer which preserves pointer provenance. +/// Data associated with an [`Event`]. This can either be a 64-bit integer +/// value or a pointer which preserves pointer provenance. #[repr(C)] #[derive(Copy, Clone)] pub union EventData { @@ -371,10 +370,12 @@ struct SixtyFourBitPointer { } /// A vector of `Event`s, plus context for interpreting them. +#[cfg(feature = "alloc")] pub struct EventVec { events: Vec, } +#[cfg(feature = "alloc")] impl EventVec { /// Constructs an `EventVec` from raw pointer, length, and capacity. /// @@ -449,6 +450,7 @@ impl EventVec { } } +#[cfg(feature = "alloc")] impl<'a> IntoIterator for &'a EventVec { type IntoIter = Iter<'a>; type Item = Event; diff --git a/vendor/rustix/src/backend/linux_raw/event/mod.rs b/vendor/rustix/src/backend/linux_raw/event/mod.rs index 4148a8c7f..605de2538 100644 --- a/vendor/rustix/src/backend/linux_raw/event/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/event/mod.rs @@ -1,4 +1,3 @@ -#[cfg(feature = "alloc")] pub mod epoll; pub(crate) mod poll_fd; pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs index c56c9152d..51c222e62 100644 --- a/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs +++ b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs @@ -31,7 +31,7 @@ bitflags! { /// `POLLRDHUP` const RDHUP = linux_raw_sys::general::POLLRDHUP as u16; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs index a8003b004..6cb8d3d96 100644 --- a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs @@ -6,17 +6,15 @@ #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] use crate::backend::c; -use crate::backend::conv::{c_int, c_uint, ret_owned_fd, ret_usize, slice_mut}; -use crate::event::{EventfdFlags, PollFd}; -use crate::fd::OwnedFd; -use crate::io; #[cfg(feature = "alloc")] -use { - crate::backend::conv::{by_ref, pass_usize, raw_fd, ret, zero}, - crate::event::epoll, - crate::fd::BorrowedFd, - linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}, +use crate::backend::conv::pass_usize; +use crate::backend::conv::{ + by_ref, c_int, c_uint, raw_fd, ret, ret_owned_fd, ret_usize, slice_mut, zero, }; +use crate::event::{epoll, EventfdFlags, PollFd}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] use { crate::backend::conv::{opt_ref, size_of}, @@ -52,13 +50,11 @@ pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result io::Result { unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_add( epfd: BorrowedFd<'_>, @@ -74,7 +70,6 @@ pub(crate) unsafe fn epoll_add( )) } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_mod( epfd: BorrowedFd<'_>, @@ -90,7 +85,6 @@ pub(crate) unsafe fn epoll_mod( )) } -#[cfg(feature = "alloc")] #[inline] pub(crate) unsafe fn epoll_del(epfd: BorrowedFd<'_>, fd: c::c_int) -> io::Result<()> { ret(syscall_readonly!( diff --git a/vendor/rustix/src/backend/linux_raw/event/types.rs b/vendor/rustix/src/backend/linux_raw/event/types.rs index 3821f8f64..eb34bd0b3 100644 --- a/vendor/rustix/src/backend/linux_raw/event/types.rs +++ b/vendor/rustix/src/backend/linux_raw/event/types.rs @@ -15,7 +15,7 @@ bitflags! { /// `EFD_SEMAPHORE` const SEMAPHORE = linux_raw_sys::general::EFD_SEMAPHORE; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs index 4df589af5..ea1017957 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/dir.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/dir.rs @@ -18,9 +18,17 @@ pub struct Dir { /// The `OwnedFd` that we read directory entries from. fd: OwnedFd, + /// Have we seen any errors in this iteration? + any_errors: bool, + + /// Should we rewind the stream on the next iteration? + rewind: bool, + + /// The buffer for `linux_dirent64` entries. buf: Vec, + + /// Where we are in the buffer. pos: usize, - next: Option, } impl Dir { @@ -38,25 +46,39 @@ impl Dir { Ok(Self { fd: fd_for_dir, + any_errors: false, + rewind: false, buf: Vec::new(), pos: 0, - next: None, }) } /// `rewinddir(self)` #[inline] pub fn rewind(&mut self) { + self.any_errors = false; + self.rewind = true; self.pos = self.buf.len(); - self.next = Some(0); } /// `readdir(self)`, where `None` means the end of the directory. pub fn read(&mut self) -> Option> { - if let Some(next) = self.next.take() { - match crate::backend::fs::syscalls::_seek(self.fd.as_fd(), next as i64, SEEK_SET) { + // If we've seen errors, don't continue to try to read anyting further. + if self.any_errors { + return None; + } + + // If a rewind was requested, seek to the beginning. + if self.rewind { + self.rewind = false; + match io::retry_on_intr(|| { + crate::backend::fs::syscalls::_seek(self.fd.as_fd(), 0, SEEK_SET) + }) { Ok(_) => (), - Err(err) => return Some(Err(err)), + Err(err) => { + self.any_errors = true; + return Some(Err(err)); + } } } @@ -78,7 +100,7 @@ impl Dir { if self.buf.len() - self.pos < size_of::() { match self.read_more()? { Ok(()) => (), - Err(e) => return Some(Err(e)), + Err(err) => return Some(Err(err)), } } @@ -136,14 +158,31 @@ impl Dir { } fn read_more(&mut self) -> Option> { - let og_len = self.buf.len(); - // Capacity increment currently chosen by wild guess. - self.buf - .resize(self.buf.capacity() + 32 * size_of::(), 0); - let nread = match crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) { + // The first few times we're called, we allocate a relatively small + // buffer, because many directories are small. If we're called more, + // use progressively larger allocations, up to a fixed maximum. + // + // The specific sizes and policy here have not been tuned in detail yet + // and may need to be adjusted. In doing so, we should be careful to + // avoid unbounded buffer growth. This buffer only exists to share the + // cost of a `getdents` call over many entries, so if it gets too big, + // cache and heap usage will outweigh the benefit. And ultimately, + // directories can contain more entries than we can allocate contiguous + // memory for, so we'll always need to cap the size at some point. + if self.buf.len() < 1024 * size_of::() { + self.buf.reserve(32 * size_of::()); + } + self.buf.resize(self.buf.capacity(), 0); + let nread = match io::retry_on_intr(|| { + crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) + }) { Ok(nread) => nread, + Err(io::Errno::NOENT) => { + self.any_errors = true; + return None; + } Err(err) => { - self.buf.resize(og_len, 0); + self.any_errors = true; return Some(Err(err)); } }; @@ -225,3 +264,33 @@ impl DirEntry { self.d_ino } } + +#[test] +fn dir_iterator_handles_io_errors() { + // create a dir, keep the FD, then delete the dir + let tmp = tempfile::tempdir().unwrap(); + let fd = crate::fs::openat( + crate::fs::CWD, + tmp.path(), + crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, + crate::fs::Mode::empty(), + ) + .unwrap(); + + let file_fd = crate::fs::openat( + &fd, + tmp.path().join("test.txt"), + crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, + crate::fs::Mode::RWXU, + ) + .unwrap(); + + let mut dir = Dir::read_from(&fd).unwrap(); + + // Reach inside the `Dir` and replace its directory with a file, which + // will cause the subsequent `getdents64` to fail. + crate::io::dup2(&file_fd, &mut dir.fd).unwrap(); + + assert!(matches!(dir.next(), Some(Err(_)))); + assert!(matches!(dir.next(), None)); +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs index ef205ffdf..aaba71d7c 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs @@ -18,7 +18,7 @@ bitflags! { /// `IN_NONBLOCK` const NONBLOCK = linux_raw_sys::general::IN_NONBLOCK; - /// + /// const _ = !0; } } @@ -38,7 +38,7 @@ bitflags! { const CLOSE_NOWRITE = linux_raw_sys::general::IN_CLOSE_NOWRITE; /// `IN_CLOSE_WRITE` const CLOSE_WRITE = linux_raw_sys::general::IN_CLOSE_WRITE; - /// `IN_CREATE ` + /// `IN_CREATE` const CREATE = linux_raw_sys::general::IN_CREATE; /// `IN_DELETE` const DELETE = linux_raw_sys::general::IN_DELETE; @@ -75,7 +75,7 @@ bitflags! { /// `IN_ONLYDIR` const ONLYDIR = linux_raw_sys::general::IN_ONLYDIR; - /// + /// const _ = !0; } } @@ -92,13 +92,12 @@ pub fn inotify_init(flags: CreateFlags) -> io::Result { /// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify. /// -/// This registers or updates a watch for the filesystem path `path` -/// and returns a watch descriptor corresponding to this watch. +/// This registers or updates a watch for the filesystem path `path` and +/// returns a watch descriptor corresponding to this watch. /// -/// Note: Due to the existence of hardlinks, providing two -/// different paths to this method may result in it returning -/// the same watch descriptor. An application should keep track of this -/// externally to avoid logic errors. +/// Note: Due to the existence of hardlinks, providing two different paths to +/// this method may result in it returning the same watch descriptor. An +/// application should keep track of this externally to avoid logic errors. #[inline] pub fn inotify_add_watch( inot: BorrowedFd<'_>, diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs index e72afb8ab..f856fa8b0 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs @@ -378,6 +378,7 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> lo(len) )) } + // On mips, the arguments are not reordered, and padding is inserted // instead to ensure alignment. #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] @@ -393,6 +394,9 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> advice )) } + + // For all other 32-bit architectures, use `fadvise64_64` so that we get a + // 64-bit length. #[cfg(all( target_pointer_width = "32", not(any( @@ -413,6 +417,8 @@ pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> advice )) } + + // On 64-bit architectures, use `fadvise64` which is sufficient. #[cfg(target_pointer_width = "64")] unsafe { ret(syscall_readonly!( @@ -951,7 +957,7 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result { } } -#[cfg(feature = "alloc")] +#[cfg(any(feature = "alloc", all(linux_kernel, feature = "procfs")))] #[inline] pub(crate) fn readlinkat( dirfd: BorrowedFd<'_>, diff --git a/vendor/rustix/src/backend/linux_raw/fs/types.rs b/vendor/rustix/src/backend/linux_raw/fs/types.rs index 6e2e14f1e..85fe018a3 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/types.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/types.rs @@ -20,7 +20,7 @@ bitflags! { /// `F_OK` const EXISTS = linux_raw_sys::general::F_OK; - /// + /// const _ = !0; } } @@ -61,7 +61,7 @@ bitflags! { /// `AT_STATX_DONT_SYNC` const STATX_DONT_SYNC = linux_raw_sys::general::AT_STATX_DONT_SYNC; - /// + /// const _ = !0; } } @@ -120,7 +120,7 @@ bitflags! { /// `S_ISVTX` const SVTX = linux_raw_sys::general::S_ISVTX; - /// + /// const _ = !0; } } @@ -179,9 +179,9 @@ bitflags! { /// Similar to `ACCMODE`, but just includes the read/write flags, and /// no other flags. /// - /// Some implementations include `O_PATH` in `O_ACCMODE`, when + /// On some platforms, `PATH` may be included in `ACCMODE`, when /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `O_PATH` may mean that the read/write + /// indicated, as the presence of `PATH` may mean that the read/write /// bits don't have their usual meaning. const RWMODE = linux_raw_sys::general::O_RDONLY | linux_raw_sys::general::O_WRONLY | @@ -250,7 +250,7 @@ bitflags! { /// `O_DIRECT` const DIRECT = linux_raw_sys::general::O_DIRECT; - /// + /// const _ = !0; } } @@ -280,7 +280,7 @@ bitflags! { /// `RESOLVE_CACHED` (since Linux 5.12) const CACHED = linux_raw_sys::general::RESOLVE_CACHED as u64; - /// + /// const _ = !0; } } @@ -301,7 +301,7 @@ bitflags! { /// `RENAME_WHITEOUT` const WHITEOUT = linux_raw_sys::general::RENAME_WHITEOUT; - /// + /// const _ = !0; } } @@ -453,7 +453,7 @@ bitflags! { /// `MFD_HUGE_16GB` const HUGE_16GB = linux_raw_sys::general::MFD_HUGE_16GB; - /// + /// const _ = !0; } } @@ -478,7 +478,7 @@ bitflags! { /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) const FUTURE_WRITE = linux_raw_sys::general::F_SEAL_FUTURE_WRITE; - /// + /// const _ = !0; } } @@ -538,7 +538,7 @@ bitflags! { /// `STATX_ALL` const ALL = linux_raw_sys::general::STATX_ALL; - /// + /// const _ = !0; } } @@ -565,7 +565,7 @@ bitflags! { /// `FALLOC_FL_UNSHARE_RANGE` const UNSHARE_RANGE = linux_raw_sys::general::FALLOC_FL_UNSHARE_RANGE; - /// + /// const _ = !0; } } @@ -602,7 +602,7 @@ bitflags! { /// `ST_SYNCHRONOUS` const SYNCHRONOUS = linux_raw_sys::general::MS_SYNCHRONOUS as u64; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs index 7730a7237..8247faa1c 100644 --- a/vendor/rustix/src/backend/linux_raw/io/errno.rs +++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs @@ -60,7 +60,7 @@ impl Errno { #[inline] pub fn from_io_error(io_err: &std::io::Error) -> Option { io_err.raw_os_error().and_then(|raw| { - // `std::io::Error` could theoretically have arbitrary "OS error" + // `std::io::Error` could theoretically have arbitrary OS error // values, so check that they're in Linux's range. if (1..4096).contains(&raw) { Some(Self::from_errno(raw as u32)) diff --git a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs index d2cbba0c3..62c68a22f 100644 --- a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs @@ -14,8 +14,8 @@ use crate::backend::conv::loff_t_from_u64; ))] use crate::backend::conv::zero; use crate::backend::conv::{ - c_uint, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd, ret_usize, slice, - slice_mut, + c_uint, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, ret_discarded_fd, ret_owned_fd, + ret_usize, slice, slice_mut, }; #[cfg(target_pointer_width = "32")] use crate::backend::conv::{hi, lo}; @@ -96,25 +96,16 @@ pub(crate) fn preadv( ) -> io::Result { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall!( __NR_preadv, fd, bufs_addr, bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_preadv, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize) )) } } @@ -128,26 +119,16 @@ pub(crate) fn preadv2( ) -> io::Result { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_preadv2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall!( __NR_preadv2, fd, bufs_addr, bufs_len, - loff_t_from_u64(pos), + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize), flags )) } @@ -217,25 +198,16 @@ pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result, bufs: &[IoSlice<'_>], pos: u64) -> io::Result { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall_readonly!( __NR_pwritev, fd, bufs_addr, bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize) )) } } @@ -249,26 +221,16 @@ pub(crate) fn pwritev2( ) -> io::Result { let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] + // Unlike the plain "p" functions, the "pv" functions pass their offset in + // an endian-independent way, and always in two registers. unsafe { ret_usize(syscall_readonly!( __NR_pwritev2, fd, bufs_addr, bufs_len, - loff_t_from_u64(pos), + pass_usize(pos as usize), + pass_usize((pos >> 32) as usize), flags )) } diff --git a/vendor/rustix/src/backend/linux_raw/io/types.rs b/vendor/rustix/src/backend/linux_raw/io/types.rs index fb7e913a0..4b3dfc686 100644 --- a/vendor/rustix/src/backend/linux_raw/io/types.rs +++ b/vendor/rustix/src/backend/linux_raw/io/types.rs @@ -12,7 +12,7 @@ bitflags! { /// `FD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC; - /// + /// const _ = !0; } } @@ -36,7 +36,7 @@ bitflags! { /// `RWF_APPEND` (since Linux 4.16) const APPEND = linux_raw_sys::general::RWF_APPEND; - /// + /// const _ = !0; } } @@ -51,7 +51,7 @@ bitflags! { /// `O_CLOEXEC` const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs index b51f826a9..3d4274cfe 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs @@ -6,6 +6,8 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +use super::types::MlockAllFlags; use super::types::{ Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, UserfaultfdFlags, @@ -210,3 +212,30 @@ pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result< pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) } + +/// Locks all pages mapped into the address space of the calling process. +/// +/// This includes the pages of the code, data, and stack segment, as well as +/// shared libraries, user space kernel data, shared memory, and memory-mapped +/// files. All mapped pages are guaranteed to be resident in RAM when the call +/// returns successfully; the pages are guaranteed to stay in RAM until later +/// unlocked. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> { + // When `mlockall` is used with `MCL_ONFAULT | MCL_FUTURE`, the ordering + // of `mlockall` with respect to arbitrary loads may be significant, + // because if a load happens and evokes a fault before the `mlockall`, + // the memory doesn't get locked, but if the load and therefore + // the fault happens after, then the memory does get locked. + // So to be conservative in this regard, we use `syscall` instead + // of `syscall_readonly` + unsafe { ret(syscall!(__NR_mlockall, flags)) } +} + +/// Unlocks all pages mapped into the address space of the calling process. +#[inline] +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +pub(crate) fn munlockall() -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_munlockall)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/mm/types.rs b/vendor/rustix/src/backend/linux_raw/mm/types.rs index 0dfb41050..b5e36640d 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/types.rs @@ -17,7 +17,7 @@ bitflags! { /// `PROT_EXEC` const EXEC = linux_raw_sys::general::PROT_EXEC; - /// + /// const _ = !0; } } @@ -56,7 +56,7 @@ bitflags! { #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] const ADI = linux_raw_sys::general::PROT_ADI; - /// + /// const _ = !0; } } @@ -106,7 +106,7 @@ bitflags! { #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6")))] const UNINITIALIZED = linux_raw_sys::general::MAP_UNINITIALIZED; - /// + /// const _ = !0; } } @@ -126,7 +126,7 @@ bitflags! { /// `MREMAP_DONTUNMAP` (since Linux 5.7) const DONTUNMAP = linux_raw_sys::general::MREMAP_DONTUNMAP; - /// + /// const _ = !0; } } @@ -148,7 +148,7 @@ bitflags! { /// written). const INVALIDATE = linux_raw_sys::general::MS_INVALIDATE; - /// + /// const _ = !0; } } @@ -163,7 +163,7 @@ bitflags! { /// `MLOCK_ONFAULT` const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; - /// + /// const _ = !0; } } @@ -240,9 +240,9 @@ pub enum Advice { impl Advice { /// `POSIX_MADV_DONTNEED` /// - /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because - /// Linux's `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See - /// `LinuxDontNeed` for the Linux behavior. + /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because Linux's + /// `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See `LinuxDontNeed` + /// for the Linux behavior. pub const DontNeed: Self = Self::Normal; } @@ -258,7 +258,39 @@ bitflags! { /// `O_NONBLOCK` const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - /// + /// + const _ = !0; + } +} + +#[cfg(any(linux_kernel, freebsdlike, netbsdlike))] +bitflags! { + /// `MCL_*` flags for use with [`mlockall`]. + /// + /// [`mlockall`]: crate::mm::mlockall + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct MlockAllFlags: u32 { + /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all + /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings + /// to lock pages when they are faulted in. When used with + /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will + /// not fault in non-present pages. When used with `MCL_FUTURE`, all + /// future mappings will be marked to lock pages when they are faulted + /// in, but they will not be populated by the lock when the mapping is + /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or + /// `MCL_FUTURE` or both. + const ONFAULT = linux_raw_sys::general::MCL_ONFAULT; + /// Lock all pages which will become mapped into the address space of + /// the process in the future. These could be, for instance, new pages + /// required by a growing heap and stack as well as new memory-mapped + /// files or shared memory regions. + const FUTURE = linux_raw_sys::general::MCL_FUTURE; + /// Lock all pages which are currently mapped into the address space of + /// the process. + const CURRENT = linux_raw_sys::general::MCL_CURRENT; + + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs index 9a07467f4..388f573dc 100644 --- a/vendor/rustix/src/backend/linux_raw/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/mod.rs @@ -67,6 +67,8 @@ pub(crate) mod pty; pub(crate) mod rand; #[cfg(feature = "runtime")] pub(crate) mod runtime; +#[cfg(feature = "shm")] +pub(crate) mod shm; #[cfg(feature = "system")] pub(crate) mod system; #[cfg(feature = "termios")] diff --git a/vendor/rustix/src/backend/linux_raw/mount/types.rs b/vendor/rustix/src/backend/linux_raw/mount/types.rs index 221f8f315..3a797ab77 100644 --- a/vendor/rustix/src/backend/linux_raw/mount/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mount/types.rs @@ -57,7 +57,7 @@ bitflags! { /// `MS_NOSYMFOLLOW` const NOSYMFOLLOW = linux_raw_sys::general::MS_NOSYMFOLLOW; - /// + /// const _ = !0; } } @@ -78,7 +78,7 @@ bitflags! { /// `UMOUNT_NOFOLLOW` const NOFOLLOW = linux_raw_sys::general::UMOUNT_NOFOLLOW; - /// + /// const _ = !0; } } @@ -94,7 +94,7 @@ bitflags! { /// `FSOPEN_CLOEXEC` const FSOPEN_CLOEXEC = linux_raw_sys::general::FSOPEN_CLOEXEC; - /// + /// const _ = !0; } } @@ -110,7 +110,7 @@ bitflags! { /// `FSMOUNT_CLOEXEC` const FSMOUNT_CLOEXEC = linux_raw_sys::general::FSMOUNT_CLOEXEC; - /// + /// const _ = !0; } } @@ -189,7 +189,7 @@ bitflags! { /// `MOUNT_ATTR__ATIME_FLAGS` const MOUNT_ATTR_SIZE_VER0 = linux_raw_sys::general::MOUNT_ATTR_SIZE_VER0; - /// + /// const _ = !0; } } @@ -230,7 +230,7 @@ bitflags! { /// `MOVE_MOUNT__MASK` const MOVE_MOUNT__MASK = linux_raw_sys::general::MOVE_MOUNT__MASK; - /// + /// const _ = !0; } } @@ -261,7 +261,7 @@ bitflags! { /// `AT_SYMLINK_NOFOLLOW` const AT_SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; - /// + /// const _ = !0; } } @@ -286,7 +286,7 @@ bitflags! { /// `FSPICK_EMPTY_PATH` const FSPICK_EMPTY_PATH = linux_raw_sys::general::FSPICK_EMPTY_PATH; - /// + /// const _ = !0; } } @@ -311,7 +311,7 @@ bitflags! { /// `MS_REC` const REC = linux_raw_sys::general::MS_REC; - /// + /// const _ = !0; } } @@ -323,7 +323,7 @@ bitflags! { const REMOUNT = linux_raw_sys::general::MS_REMOUNT; const MOVE = linux_raw_sys::general::MS_MOVE; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs index 2b6ab34ba..f83c54621 100644 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/net/mod.rs @@ -2,5 +2,6 @@ pub(crate) mod addr; pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; +pub(crate) mod sockopt; pub(crate) mod syscalls; pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs index 659093920..2b88bfbbc 100644 --- a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs @@ -122,7 +122,7 @@ pub(crate) fn with_unix_msghdr( f: impl FnOnce(c::msghdr) -> R, ) -> R { f(c::msghdr { - msg_name: as_ptr(addr) as _, + msg_name: as_ptr(&addr.unix) as _, msg_namelen: addr.addr_len() as _, msg_iov: iov.as_ptr() as _, msg_iovlen: msg_iov_len(iov.len()), diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs index f4b7d9914..af7282c98 100644 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs @@ -1,5 +1,5 @@ -//! The BSD sockets API requires us to read the `ss_family` field before -//! we can interpret the rest of a `sockaddr` produced by the kernel. +//! The BSD sockets API requires us to read the `ss_family` field before we can +//! interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] use crate::backend::c; @@ -110,7 +110,7 @@ pub(crate) unsafe fn read_sockaddr( } } -/// Read a socket address returned from the OS. +/// Read an optional socket address returned from the OS. /// /// # Safety /// diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs index 43b35341a..d5cdd075e 100644 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs @@ -2,7 +2,8 @@ use crate::backend::c; use bitflags::bitflags; bitflags! { - /// `MSG_* flags for use with [`send`], [`send_to`], and related functions. + /// `MSG_*` flags for use with [`send`], [`send_to`], and related + /// functions. /// /// [`send`]: crate::net::send /// [`sendto`]: crate::net::sendto @@ -24,13 +25,14 @@ bitflags! { /// `MSG_OOB` const OOB = c::MSG_OOB; - /// + /// const _ = !0; } } bitflags! { - /// `MSG_* flags for use with [`recv`], [`recvfrom`], and related functions. + /// `MSG_*` flags for use with [`recv`], [`recvfrom`], and related + /// functions. /// /// [`recv`]: crate::net::recv /// [`recvfrom`]: crate::net::recvfrom @@ -52,7 +54,7 @@ bitflags! { /// `MSG_WAITALL` const WAITALL = c::MSG_WAITALL; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/net/sockopt.rs b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs new file mode 100644 index 000000000..6a740bbf7 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/sockopt.rs @@ -0,0 +1,879 @@ +//! linux_raw syscalls supporting `rustix::net::sockopt`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{by_mut, c_uint, ret, socklen_t}; +use crate::fd::BorrowedFd; +#[cfg(feature = "alloc")] +use crate::ffi::CStr; +use crate::io; +use crate::net::sockopt::Timeout; +use crate::net::{ + AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RawProtocol, SocketAddrAny, SocketAddrStorage, + SocketAddrV4, SocketAddrV6, SocketType, UCred, +}; +#[cfg(feature = "alloc")] +use alloc::borrow::ToOwned; +#[cfg(feature = "alloc")] +use alloc::string::String; +use core::mem::MaybeUninit; +use core::time::Duration; +use linux_raw_sys::general::{__kernel_old_timeval, __kernel_sock_timeval}; +#[cfg(target_arch = "x86")] +use { + crate::backend::conv::{slice_just_addr, x86_sys}, + crate::backend::reg::{ArgReg, SocketArg}, + linux_raw_sys::net::{SYS_GETSOCKOPT, SYS_SETSOCKOPT}, +}; + +#[inline] +fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { + let mut optlen: c::socklen_t = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + let mut value = MaybeUninit::::uninit(); + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + assert_eq!( + optlen as usize, + core::mem::size_of::(), + "unexpected getsockopt size" + ); + + unsafe { Ok(value.assume_init()) } +} + +#[inline] +fn getsockopt_raw( + fd: BorrowedFd<'_>, + level: u32, + optname: u32, + value: &mut MaybeUninit, + optlen: &mut c::socklen_t, +) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall!( + __NR_getsockopt, + fd, + c_uint(level), + c_uint(optname), + value, + by_mut(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + value.into(), + by_mut(optlen), + ]) + )) + } +} + +#[inline] +fn setsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32, value: T) -> io::Result<()> { + let optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + setsockopt_raw(fd, level, optname, &value, optlen) +} + +#[inline] +fn setsockopt_raw( + fd: BorrowedFd<'_>, + level: u32, + optname: u32, + ptr: *const T, + optlen: c::socklen_t, +) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_setsockopt, + fd, + c_uint(level), + c_uint(optname), + ptr, + socklen_t(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + ptr.into(), + socklen_t(optlen), + ]) + )) + } +} + +#[inline] +pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_TYPE) +} + +#[inline] +pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR, from_bool(reuseaddr)) +} + +#[inline] +pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEADDR).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST, from_bool(broadcast)) +} + +#[inline] +pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_BROADCAST).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_linger(fd: BorrowedFd<'_>, linger: Option) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + duration_to_secs(linger)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: c::c_int::from(linger.is_some()), + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET, c::SO_LINGER, linger) +} + +#[inline] +pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { + let linger: c::linger = getsockopt(fd, c::SOL_SOCKET, c::SO_LINGER)?; + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) +} + +#[inline] +pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED, from_bool(passcred)) +} + +#[inline] +pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_PASSCRED).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, +) -> io::Result<()> { + let time = duration_to_linux_sock_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + match setsockopt(fd, c::SOL_SOCKET, optname, time) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + set_socket_timeout_old(fd, id, timeout) + } + otherwise => otherwise, + } +} + +/// Same as `set_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn set_socket_timeout_old( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, +) -> io::Result<()> { + let time = duration_to_linux_old_timeval(timeout)?; + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + setsockopt(fd, c::SOL_SOCKET, optname, time) +} + +#[inline] +pub(crate) fn get_socket_timeout(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_NEW, + Timeout::Send => c::SO_SNDTIMEO_NEW, + }; + let time: __kernel_sock_timeval = match getsockopt(fd, c::SOL_SOCKET, optname) { + Err(io::Errno::NOPROTOOPT) if c::SO_RCVTIMEO_NEW != c::SO_RCVTIMEO_OLD => { + return get_socket_timeout_old(fd, id) + } + otherwise => otherwise?, + }; + Ok(duration_from_linux_sock_timeval(time)) +} + +/// Same as `get_socket_timeout` but uses `__kernel_old_timeval` instead of +/// `__kernel_sock_timeval` and `_OLD` constants instead of `_NEW`. +fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO_OLD, + Timeout::Send => c::SO_SNDTIMEO_OLD, + }; + let time: __kernel_old_timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + Ok(duration_from_linux_old_timeval(time)) +} + +/// Convert a `__linux_sock_timeval` to a Rust `Option`. +#[inline] +fn duration_from_linux_sock_timeval(time: __kernel_sock_timeval) -> Option { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Like `duration_from_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_from_linux_old_timeval(time: __kernel_old_timeval) -> Option { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some(Duration::from_secs(time.tv_sec as u64) + Duration::from_micros(time.tv_usec as u64)) + } +} + +/// Convert a Rust `Option` to a `__kernel_sock_timeval`. +#[inline] +fn duration_to_linux_sock_timeval(timeout: Option) -> io::Result<__kernel_sock_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_sock_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_sock_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +/// Like `duration_to_linux` but uses Linux's old 32-bit +/// `__kernel_old_timeval`. +fn duration_to_linux_old_timeval(timeout: Option) -> io::Result<__kernel_old_timeval> { + Ok(match timeout { + Some(timeout) => { + if timeout == Duration::ZERO { + return Err(io::Errno::INVAL); + } + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = __kernel_old_timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => __kernel_old_timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) +} + +#[inline] +pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { + let err: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_ERROR)?; + Ok(if err == 0 { + Ok(()) + } else { + Err(io::Errno::from_raw_os_error(err)) + }) +} + +#[inline] +pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE, from_bool(keepalive)) +} + +#[inline] +pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_KEEPALIVE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF, size) +} + +#[inline] +pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_RCVBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::INVAL)?; + setsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF, size) +} + +#[inline] +pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_SNDBUF).map(|size: u32| size as usize) +} + +#[inline] +pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { + let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET, c::SO_DOMAIN)?; + Ok(AddressFamily( + domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + )) +} + +#[inline] +pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_ACCEPTCONN).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_oobinline(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_oobinline(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_OOBINLINE).map(to_bool) +} + +#[inline] +pub(crate) fn set_socket_reuseport(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT, from_bool(value)) +} + +#[inline] +pub(crate) fn get_socket_reuseport(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_REUSEPORT).map(to_bool) +} + +#[inline] +pub(crate) fn get_socket_protocol(fd: BorrowedFd<'_>) -> io::Result> { + getsockopt(fd, c::SOL_SOCKET, c::SO_PROTOCOL) + .map(|raw: u32| RawProtocol::new(raw).map(Protocol::from_raw)) +} + +#[inline] +pub(crate) fn get_socket_cookie(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_COOKIE) +} + +#[inline] +pub(crate) fn get_socket_incoming_cpu(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU) +} + +#[inline] +pub(crate) fn set_socket_incoming_cpu(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET, c::SO_INCOMING_CPU, value) +} + +#[inline] +pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TTL, ttl) +} + +#[inline] +pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IP_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY, from_bool(only_v6)) +} + +#[inline] +pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_V6ONLY).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl) +} + +#[inline] +pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IP_MULTICAST_TTL) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_loop(fd: BorrowedFd<'_>, multicast_loop: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_multicast_hops(fd: BorrowedFd<'_>, multicast_hops: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS, multicast_hops) +} + +#[inline] +pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IPV6_MULTICAST_HOPS) +} + +#[inline] +pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_add_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreqn) +} + +#[inline] +pub(crate) fn set_ip_add_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_ADD_SOURCE_MEMBERSHIP, mreq_source) +} + +#[inline] +pub(crate) fn set_ip_drop_source_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> io::Result<()> { + let mreq_source = to_imr_source(multiaddr, interface, sourceaddr); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_SOURCE_MEMBERSHIP, mreq_source) +} + +#[inline] +pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_ADD_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, +) -> io::Result<()> { + let mreq = to_ip_mreq(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn set_ip_drop_membership_with_ifindex( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + address: &Ipv4Addr, + ifindex: i32, +) -> io::Result<()> { + let mreqn = to_ip_mreqn(multiaddr, address, ifindex); + setsockopt(fd, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreqn) +} + +#[inline] +pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, +) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_DROP_MEMBERSHIP, mreq) +} + +#[inline] +pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) +} + +#[inline] +pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { + let hops = match hops { + Some(hops) => hops.into(), + None => -1, + }; + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_UNICAST_HOPS, hops) +} + +#[inline] +pub(crate) fn set_ip_tos(fd: BorrowedFd<'_>, value: u8) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_TOS, i32::from(value)) +} + +#[inline] +pub(crate) fn get_ip_tos(fd: BorrowedFd<'_>) -> io::Result { + let value: i32 = getsockopt(fd, c::IPPROTO_IP, c::IP_TOS)?; + Ok(value as u8) +} + +#[inline] +pub(crate) fn set_ip_recvtos(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ip_recvtos(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IP_RECVTOS).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_recvtclass(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ipv6_recvtclass(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_RECVTCLASS).map(to_bool) +} + +#[inline] +pub(crate) fn set_ip_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ip_freebind(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP, c::IP_FREEBIND).map(to_bool) +} + +#[inline] +pub(crate) fn set_ipv6_freebind(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND, from_bool(value)) +} + +#[inline] +pub(crate) fn get_ipv6_freebind(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_FREEBIND).map(to_bool) +} + +#[inline] +pub(crate) fn get_ip_original_dst(fd: BorrowedFd<'_>) -> io::Result { + let level = c::IPPROTO_IP; + let optname = c::SO_ORIGINAL_DST; + let mut value = MaybeUninit::::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V4(v4) => Ok(v4), + _ => unreachable!(), + } +} + +#[inline] +pub(crate) fn get_ipv6_original_dst(fd: BorrowedFd<'_>) -> io::Result { + let level = c::IPPROTO_IPV6; + let optname = c::IP6T_SO_ORIGINAL_DST; + let mut value = MaybeUninit::::uninit(); + let mut optlen = core::mem::size_of_val(&value).try_into().unwrap(); + + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + + let any = unsafe { SocketAddrAny::read(value.as_ptr(), optlen as usize)? }; + match any { + SocketAddrAny::V6(v6) => Ok(v6), + _ => unreachable!(), + } +} + +#[inline] +pub(crate) fn set_ipv6_tclass(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS, value) +} + +#[inline] +pub(crate) fn get_ipv6_tclass(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6, c::IPV6_TCLASS) +} + +#[inline] +pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY, from_bool(nodelay)) +} + +#[inline] +pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_NODELAY).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT, count) +} + +#[inline] +pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPCNT) +} + +#[inline] +pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPIDLE)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { + let secs: c::c_uint = duration_to_secs(duration)?; + setsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL, secs) +} + +#[inline] +pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { + let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP, c::TCP_KEEPINTVL)?; + Ok(Duration::from_secs(secs as u64)) +} + +#[inline] +pub(crate) fn set_tcp_user_timeout(fd: BorrowedFd<'_>, value: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT, value) +} + +#[inline] +pub(crate) fn get_tcp_user_timeout(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_USER_TIMEOUT) +} + +#[inline] +pub(crate) fn set_tcp_quickack(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK, from_bool(value)) +} + +#[inline] +pub(crate) fn get_tcp_quickack(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_QUICKACK).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_congestion(fd: BorrowedFd<'_>, value: &str) -> io::Result<()> { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + let optlen = value.len().try_into().unwrap(); + setsockopt_raw(fd, level, optname, value.as_ptr(), optlen) +} + +#[cfg(feature = "alloc")] +#[inline] +pub(crate) fn get_tcp_congestion(fd: BorrowedFd<'_>) -> io::Result { + let level = c::IPPROTO_TCP; + let optname = c::TCP_CONGESTION; + const OPTLEN: c::socklen_t = 16; + let mut value = MaybeUninit::<[MaybeUninit; OPTLEN as usize]>::uninit(); + let mut optlen = OPTLEN; + getsockopt_raw(fd, level, optname, &mut value, &mut optlen)?; + unsafe { + let value = value.assume_init(); + let slice: &[u8] = core::mem::transmute(&value[..optlen as usize]); + assert!(slice.iter().any(|b| *b == b'\0')); + Ok( + core::str::from_utf8(CStr::from_ptr(slice.as_ptr().cast()).to_bytes()) + .unwrap() + .to_owned(), + ) + } +} + +#[inline] +pub(crate) fn set_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_TCP, + c::TCP_THIN_LINEAR_TIMEOUTS, + from_bool(value), + ) +} + +#[inline] +pub(crate) fn get_tcp_thin_linear_timeouts(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_THIN_LINEAR_TIMEOUTS).map(to_bool) +} + +#[inline] +pub(crate) fn set_tcp_cork(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK, from_bool(value)) +} + +#[inline] +pub(crate) fn get_tcp_cork(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP, c::TCP_CORK).map(to_bool) +} + +#[inline] +pub(crate) fn get_socket_peercred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERCRED) +} + +#[inline] +fn to_ip_mreq(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } +} + +#[inline] +fn to_ip_mreqn(multiaddr: &Ipv4Addr, address: &Ipv4Addr, ifindex: i32) -> c::ip_mreqn { + c::ip_mreqn { + imr_multiaddr: to_imr_addr(multiaddr), + imr_address: to_imr_addr(address), + imr_ifindex: ifindex, + } +} + +#[inline] +fn to_imr_source( + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + sourceaddr: &Ipv4Addr, +) -> c::ip_mreq_source { + c::ip_mreq_source { + imr_multiaddr: to_imr_addr(multiaddr).s_addr, + imr_interface: to_imr_addr(interface).s_addr, + imr_sourceaddr: to_imr_addr(sourceaddr).s_addr, + } +} + +#[inline] +fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + c::in_addr { + s_addr: u32::from_ne_bytes(addr.octets()), + } +} + +#[inline] +fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_ifindex: to_ipv6mr_interface(interface), + } +} + +#[inline] +fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + c::in6_addr { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { + u6_addr8: multiaddr.octets(), + }, + } +} + +#[inline] +fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int +} + +#[inline] +fn from_bool(value: bool) -> c::c_uint { + c::c_uint::from(value) +} + +#[inline] +fn to_bool(value: c::c_uint) -> bool { + value != 0 +} + +/// Convert to seconds, rounding up if necessary. +#[inline] +fn duration_to_secs>(duration: Duration) -> io::Result { + let mut secs = duration.as_secs(); + if duration.subsec_nanos() != 0 { + secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; + } + T::try_from(secs).map_err(|_e| io::Errno::INVAL) +} diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs index e5ebcc1dd..f513f1261 100644 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -30,8 +30,8 @@ use { crate::backend::reg::{ArgReg, SocketArg}, linux_raw_sys::net::{ SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, - SYS_SENDTO, SYS_SETSOCKOPT, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, + SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, SYS_SENDTO, + SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, }, }; @@ -905,627 +905,45 @@ pub(crate) fn connect_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Res } #[inline] -pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { +pub(crate) fn connect_unspec(fd: BorrowedFd<'_>) -> io::Result<()> { + debug_assert_eq!(c::AF_UNSPEC, 0); + let addr = MaybeUninit::::zeroed(); + #[cfg(not(target_arch = "x86"))] unsafe { - ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) + ret(syscall_readonly!( + __NR_connect, + fd, + by_ref(&addr), + size_of::() + )) } #[cfg(target_arch = "x86")] unsafe { ret(syscall_readonly!( __NR_socketcall, - x86_sys(SYS_LISTEN), - slice_just_addr::, _>(&[fd.into(), c_int(backlog)]) + x86_sys(SYS_CONNECT), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&addr), + size_of::(), + ]) )) } } -pub(crate) mod sockopt { - use super::{c, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType}; - use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD}; - use core::time::Duration; - use linux_raw_sys::general::{__kernel_timespec, timeval}; - use linux_raw_sys::net::{SO_ACCEPTCONN, TCP_KEEPCNT, TCP_KEEPIDLE, TCP_KEEPINTVL}; - - #[inline] - fn getsockopt(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { - use super::*; - - let mut optlen = core::mem::size_of::(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - &mut value, - by_mut(&mut optlen) - ))?; - - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - (&mut value).into(), - by_mut(&mut optlen), - ]) - ))?; - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - } - - #[inline] - fn setsockopt( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen), - ]) - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn get_socket_reuseaddr(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_REUSEADDR).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - duration_to_secs(linger)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[inline] - pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) - } - - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } - } - - /// Same as `set_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux_old(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - let time: __kernel_timespec = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - return get_socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux(time)) - } - - /// Same as `get_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - let time: timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old(time)) - } - - /// Convert a C `timespec` to a Rust `Option`. - #[inline] - fn duration_from_linux(time: __kernel_timespec) -> Option { - if time.tv_sec == 0 && time.tv_nsec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) + Duration::from_nanos(time.tv_nsec as u64), - ) - } - } - - /// Like `duration_from_linux` but uses Linux's old 32-bit `timeval`. - fn duration_from_linux_old(time: timeval) -> Option { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) - + Duration::from_micros(time.tv_usec as u64), - ) - } - } - - /// Convert a Rust `Option` to a C `timespec`. - #[inline] - fn duration_to_linux(timeout: Option) -> io::Result<__kernel_timespec> { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - let mut timeout = __kernel_timespec { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_nsec: timeout.subsec_nanos().into(), - }; - if timeout.tv_sec == 0 && timeout.tv_nsec == 0 { - timeout.tv_nsec = 1; - } - timeout - } - None => __kernel_timespec { - tv_sec: 0, - tv_nsec: 0, - }, - }) - } - - /// Like `duration_to_linux` but uses Linux's old 32-bit `timeval`. - fn duration_to_linux_old(timeout: Option) -> io::Result { - Ok(match timeout { - Some(timeout) => { - if timeout == Duration::ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) - } - - #[inline] - pub(crate) fn get_socket_error(fd: BorrowedFd<'_>) -> io::Result> { - let err: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_ERROR)?; - Ok(if err == 0 { - Ok(()) - } else { - Err(io::Errno::from_raw_os_error(err)) - }) - } - - #[inline] - pub(crate) fn set_socket_keepalive(fd: BorrowedFd<'_>, keepalive: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_KEEPALIVE, - from_bool(keepalive), - ) - } - - #[inline] - pub(crate) fn get_socket_keepalive(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_KEEPALIVE).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_recv_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF, size) - } - - #[inline] - pub(crate) fn get_socket_recv_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_RCVBUF).map(|size: u32| size as usize) - } - - #[inline] - pub(crate) fn set_socket_send_buffer_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { - let size: c::c_int = size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF, size) - } - - #[inline] - pub(crate) fn get_socket_send_buffer_size(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize) +#[inline] +pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) } - - #[inline] - pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result { - let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?; - Ok(AddressFamily( - domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?, + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_LISTEN), + slice_just_addr::, _>(&[fd.into(), c_int(backlog)]) )) } - - #[inline] - pub(crate) fn get_socket_acceptconn(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, SO_ACCEPTCONN).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_hops( - fd: BorrowedFd<'_>, - multicast_hops: u32, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IPV6_MULTICAST_HOPS, - multicast_hops, - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn get_ipv6_unicast_hops(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS).map(|hops: c::c_int| hops as u8) - } - - #[inline] - pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option) -> io::Result<()> { - let hops = match hops { - Some(hops) => hops.into(), - None => -1, - }; - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - pub(crate) fn set_tcp_keepcnt(fd: BorrowedFd<'_>, count: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT, count) - } - - #[inline] - pub(crate) fn get_tcp_keepcnt(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPCNT) - } - - #[inline] - pub(crate) fn set_tcp_keepidle(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepidle(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPIDLE)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - pub(crate) fn set_tcp_keepintvl(fd: BorrowedFd<'_>, duration: Duration) -> io::Result<()> { - let secs: c::c_uint = duration_to_secs(duration)?; - setsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL, secs) - } - - #[inline] - pub(crate) fn get_tcp_keepintvl(fd: BorrowedFd<'_>) -> io::Result { - let secs: c::c_uint = getsockopt(fd, c::IPPROTO_TCP as _, TCP_KEEPINTVL)?; - Ok(Duration::from_secs(secs as u64)) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } - } - - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[inline] - fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) - } - - #[inline] - fn to_bool(value: c::c_uint) -> bool { - value != 0 - } - - /// Convert to seconds, rounding up if necessary. - #[inline] - fn duration_to_secs>(duration: Duration) -> io::Result { - let mut secs = duration.as_secs(); - if duration.subsec_nanos() != 0 { - secs = secs.checked_add(1).ok_or(io::Errno::INVAL)?; - } - T::try_from(secs).map_err(|_e| io::Errno::INVAL) - } } diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs index 417f76e43..24edd4948 100644 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs @@ -1,5 +1,5 @@ -//! The BSD sockets API requires us to read the `ss_family` field before -//! we can interpret the rest of a `sockaddr` produced by the kernel. +//! The BSD sockets API requires us to read the `ss_family` field before we can +//! interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] use crate::backend::c; diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs index 8b0423ae4..fbbcdea29 100644 --- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs @@ -15,6 +15,8 @@ use crate::utils::{as_ptr, check_raw_pointer}; use alloc::vec::Vec; use core::mem::size_of; use core::ptr::{null_mut, read_unaligned, NonNull}; +#[cfg(feature = "runtime")] +use core::sync::atomic::AtomicU8; use core::sync::atomic::Ordering::Relaxed; use core::sync::atomic::{AtomicPtr, AtomicUsize}; use linux_raw_sys::elf::*; @@ -22,7 +24,9 @@ use linux_raw_sys::general::{ AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; #[cfg(feature = "runtime")] -use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM}; +use linux_raw_sys::general::{ + AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE, AT_UID, +}; #[cfg(feature = "param")] #[inline] @@ -80,6 +84,23 @@ pub(crate) fn linux_execfn() -> &'static CStr { unsafe { CStr::from_ptr(execfn.cast()) } } +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn linux_secure() -> bool { + let mut secure = SECURE.load(Relaxed); + + // 0 means not initialized yet. + if secure == 0 { + init_auxv(); + secure = SECURE.load(Relaxed); + } + + // 0 means not present. Libc `getauxval(AT_SECURE)` would return 0. + // 1 means not in secure mode. + // 2 means in secure mode. + secure > 1 +} + #[cfg(feature = "runtime")] #[inline] pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { @@ -131,6 +152,8 @@ static HWCAP2: AtomicUsize = AtomicUsize::new(0); static EXECFN: AtomicPtr = AtomicPtr::new(null_mut()); static SYSINFO_EHDR: AtomicPtr = AtomicPtr::new(null_mut()); #[cfg(feature = "runtime")] +static SECURE: AtomicU8 = AtomicU8::new(0); +#[cfg(feature = "runtime")] static PHDR: AtomicPtr = AtomicPtr::new(null_mut()); #[cfg(feature = "runtime")] static PHENT: AtomicUsize = AtomicUsize::new(0); @@ -142,7 +165,7 @@ static ENTRY: AtomicUsize = AtomicUsize::new(0); #[cfg(feature = "alloc")] fn pr_get_auxv() -> crate::io::Result> { use super::super::conv::{c_int, pass_usize, ret_usize}; - const PR_GET_AUXV: c::c_int = 0x41555856; + const PR_GET_AUXV: c::c_int = 0x4155_5856; let mut buffer = alloc::vec![0u8; 512]; let len = unsafe { ret_usize(syscall_always_asm!( @@ -256,6 +279,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti let mut execfn = null_mut(); let mut sysinfo_ehdr = null_mut(); #[cfg(feature = "runtime")] + let mut secure = 0; + #[cfg(feature = "runtime")] let mut phdr = null_mut(); #[cfg(feature = "runtime")] let mut phnum = 0; @@ -263,6 +288,14 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti let mut phent = 0; #[cfg(feature = "runtime")] let mut entry = 0; + #[cfg(feature = "runtime")] + let mut uid = None; + #[cfg(feature = "runtime")] + let mut euid = None; + #[cfg(feature = "runtime")] + let mut gid = None; + #[cfg(feature = "runtime")] + let mut egid = None; for Elf_auxv_t { a_type, a_val } in aux_iter { match a_type as _ { @@ -277,6 +310,16 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti let _ = check_elf_base(a_val.cast())?; } + #[cfg(feature = "runtime")] + AT_SECURE => secure = (a_val as usize != 0) as u8 + 1, + #[cfg(feature = "runtime")] + AT_UID => uid = Some(a_val), + #[cfg(feature = "runtime")] + AT_EUID => euid = Some(a_val), + #[cfg(feature = "runtime")] + AT_GID => gid = Some(a_val), + #[cfg(feature = "runtime")] + AT_EGID => egid = Some(a_val), #[cfg(feature = "runtime")] AT_PHDR => phdr = check_raw_pointer::(a_val as *mut _)?.as_ptr(), #[cfg(feature = "runtime")] @@ -294,8 +337,16 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti #[cfg(feature = "runtime")] assert_eq!(phent, size_of::()); - // The base and sysinfo_ehdr (if present) matches our platform. Accept - // the aux values. + // If we're running set-uid or set-gid, enable “secure execution” mode, + // which doesn't do much, but users may be depending on the things that + // it does do. + #[cfg(feature = "runtime")] + if uid != euid || gid != egid { + secure = 2; + } + + // The base and sysinfo_ehdr (if present) matches our platform. Accept the + // aux values. PAGE_SIZE.store(pagesz, Relaxed); CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed); HWCAP.store(hwcap, Relaxed); @@ -303,6 +354,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti EXECFN.store(execfn, Relaxed); SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed); #[cfg(feature = "runtime")] + SECURE.store(secure, Relaxed); + #[cfg(feature = "runtime")] PHDR.store(phdr, Relaxed); #[cfg(feature = "runtime")] PHNUM.store(phnum, Relaxed); diff --git a/vendor/rustix/src/backend/linux_raw/param/init.rs b/vendor/rustix/src/backend/linux_raw/param/init.rs index 46aae009a..a63212507 100644 --- a/vendor/rustix/src/backend/linux_raw/param/init.rs +++ b/vendor/rustix/src/backend/linux_raw/param/init.rs @@ -10,13 +10,15 @@ use crate::backend::c; use crate::ffi::CStr; use core::ffi::c_void; use core::ptr::{null_mut, read, NonNull}; +#[cfg(feature = "runtime")] +use core::sync::atomic::AtomicBool; use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use linux_raw_sys::elf::*; use linux_raw_sys::general::{ AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR, }; #[cfg(feature = "runtime")] -use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM}; +use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE}; #[cfg(feature = "param")] #[inline] @@ -51,6 +53,12 @@ pub(crate) fn linux_execfn() -> &'static CStr { unsafe { CStr::from_ptr(execfn.cast()) } } +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn linux_secure() -> bool { + unsafe { SECURE.load(Ordering::Relaxed) } +} + #[cfg(feature = "runtime")] #[inline] pub(crate) fn exe_phdrs() -> (*const c_void, usize, usize) { @@ -84,6 +92,8 @@ static mut SYSINFO_EHDR: AtomicPtr = AtomicPtr::new(null_mut()); // Initialize `EXECFN` to a valid `CStr` pointer so that we don't need to check // for null on every `execfn` call. static mut EXECFN: AtomicPtr = AtomicPtr::new(b"\0".as_ptr() as _); +#[cfg(feature = "runtime")] +static mut SECURE: AtomicBool = AtomicBool::new(false); // Use `dangling` so that we can always treat it like an empty slice. #[cfg(feature = "runtime")] static mut PHDR: AtomicPtr = AtomicPtr::new(NonNull::dangling().as_ptr()); @@ -132,6 +142,8 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { AT_EXECFN => EXECFN.store(a_val.cast::(), Ordering::Relaxed), AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::(), Ordering::Relaxed), + #[cfg(feature = "runtime")] + AT_SECURE => SECURE.store(a_val as usize != 0, Ordering::Relaxed), #[cfg(feature = "runtime")] AT_PHDR => PHDR.store(a_val.cast::(), Ordering::Relaxed), #[cfg(feature = "runtime")] diff --git a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs index 0e6ca6ed5..311cf961b 100644 --- a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs @@ -34,6 +34,7 @@ const AT_PHNUM: c::c_ulong = 5; const AT_ENTRY: c::c_ulong = 9; const AT_HWCAP: c::c_ulong = 16; const AT_HWCAP2: c::c_ulong = 26; +const AT_SECURE: c::c_ulong = 23; const AT_EXECFN: c::c_ulong = 31; const AT_SYSINFO_EHDR: c::c_ulong = 33; @@ -59,6 +60,7 @@ fn test_abi() { const_assert_eq!(self::AT_HWCAP, ::libc::AT_HWCAP); const_assert_eq!(self::AT_HWCAP2, ::libc::AT_HWCAP2); const_assert_eq!(self::AT_EXECFN, ::libc::AT_EXECFN); + const_assert_eq!(self::AT_SECURE, ::libc::AT_SECURE); const_assert_eq!(self::AT_SYSINFO_EHDR, ::libc::AT_SYSINFO_EHDR); #[cfg(feature = "runtime")] const_assert_eq!(self::AT_PHDR, ::libc::AT_PHDR); @@ -120,6 +122,12 @@ pub(crate) fn linux_execfn() -> &'static CStr { } } +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn linux_secure() -> bool { + unsafe { getauxval(AT_SECURE) as usize != 0 } +} + #[cfg(feature = "runtime")] #[inline] pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { @@ -131,8 +139,8 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { } } -/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, -/// so if we don't see it, this function returns a null pointer. +/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, so +/// if we don't see it, this function returns a null pointer. #[inline] pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { #[cfg(not(feature = "runtime"))] diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs index c950b5d0a..fdddb89e1 100644 --- a/vendor/rustix/src/backend/linux_raw/pipe/types.rs +++ b/vendor/rustix/src/backend/linux_raw/pipe/types.rs @@ -16,7 +16,7 @@ bitflags! { /// `O_NONBLOCK` const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - /// + /// const _ = !0; } } @@ -36,7 +36,7 @@ bitflags! { /// `SPLICE_F_GIFT` const GIFT = linux_raw_sys::general::SPLICE_F_GIFT; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs index c0416bf5a..931f2ff2a 100644 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -141,7 +141,7 @@ pub(crate) fn getpgrp() -> Pid { #[inline] pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { unsafe { - // The raw linux syscall returns the size (in bytes) of the `cpumask_t` + // The raw Linux syscall returns the size (in bytes) of the `cpumask_t` // data type that is used internally by the kernel to represent the CPU // set bit mask. let size = ret_usize(syscall!( @@ -435,6 +435,11 @@ pub(crate) fn waitpid( _waitpid(Pid::as_raw(pid), waitopts) } +#[inline] +pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result> { + _waitpid(-pgid.as_raw_nonzero().get(), waitopts) +} + #[inline] pub(crate) fn _waitpid( pid: RawPid, @@ -459,6 +464,7 @@ pub(crate) fn waitid(id: WaitId<'_>, options: WaitidOptions) -> io::Result _waitid_all(options), WaitId::Pid(pid) => _waitid_pid(pid, options), + WaitId::Pgid(pid) => _waitid_pgid(pid, options), WaitId::PidFd(fd) => _waitid_pidfd(fd, options), } } @@ -501,6 +507,25 @@ fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result, options: WaitidOptions) -> io::Result> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::::zeroed(); + unsafe { + ret(syscall!( + __NR_waitid, + c_uint(c::P_PGID), + c_int(Pid::as_raw(pgid)), + by_mut(&mut status), + c_int(options.bits() as _), + zero() + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + #[inline] fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result> { // `waitid` can return successfully without initializing the struct (no diff --git a/vendor/rustix/src/backend/linux_raw/rand/types.rs b/vendor/rustix/src/backend/linux_raw/rand/types.rs index 47b996d30..9bc857fdd 100644 --- a/vendor/rustix/src/backend/linux_raw/rand/types.rs +++ b/vendor/rustix/src/backend/linux_raw/rand/types.rs @@ -14,7 +14,7 @@ bitflags! { /// `GRND_INSECURE` const INSECURE = linux_raw_sys::general::GRND_INSECURE; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/reg.rs b/vendor/rustix/src/backend/linux_raw/reg.rs index c4e495c52..10f95a5f9 100644 --- a/vendor/rustix/src/backend/linux_raw/reg.rs +++ b/vendor/rustix/src/backend/linux_raw/reg.rs @@ -1,8 +1,8 @@ //! Encapsulation for system call arguments and return values. //! //! The inline-asm code paths do some amount of reordering of arguments; to -//! ensure that we don't accidentally misroute an argument or return value, -//! we use distinct types for each argument index and return value. +//! ensure that we don't accidentally misroute an argument or return value, we +//! use distinct types for each argument index and return value. //! //! # Safety //! @@ -23,8 +23,8 @@ pub(super) trait ToAsm: private::Sealed { /// /// # Safety /// - /// This should be used immediately before the syscall instruction, and - /// the returned value shouldn't be used for any other purpose. + /// This should be used immediately before the syscall instruction, and the + /// returned value shouldn't be used for any other purpose. #[must_use] unsafe fn to_asm(self) -> *mut Opaque; } @@ -35,8 +35,8 @@ pub(super) trait FromAsm: private::Sealed { /// /// # Safety /// - /// This should be used immediately after the syscall instruction, and - /// the operand value shouldn't be used for any other purpose. + /// This should be used immediately after the syscall instruction, and the + /// operand value shouldn't be used for any other purpose. #[must_use] unsafe fn from_asm(raw: *mut Opaque) -> Self; } diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs index c1ff3d239..1bc461c04 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -9,7 +9,8 @@ use crate::backend::c; #[cfg(target_arch = "x86")] use crate::backend::conv::by_mut; use crate::backend::conv::{ - by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, size_of, zero, + by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_void_star, size_of, + zero, }; #[cfg(feature = "fs")] use crate::fd::BorrowedFd; @@ -22,6 +23,7 @@ use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; use crate::signal::Signal; use crate::timespec::Timespec; use crate::utils::option_as_ptr; +use core::ffi::c_void; use core::mem::MaybeUninit; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::__kernel_old_timespec; @@ -263,3 +265,9 @@ unsafe fn sigtimedwait_old( pub(crate) fn exit_group(code: c::c_int) -> ! { unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } } + +#[inline] +pub(crate) unsafe fn brk(addr: *mut c::c_void) -> io::Result<*mut c_void> { + // Don't mark this `readonly`, so that loads don't get reordered past it. + ret_void_star(syscall!(__NR_brk, addr)) +} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs index ad1634894..69bd5cef1 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs @@ -8,6 +8,7 @@ use crate::backend::c; use crate::backend::param::auxv::exe_phdrs; +use core::arch::global_asm; use core::ptr::{null, NonNull}; use linux_raw_sys::elf::*; @@ -25,6 +26,10 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { let (first_phdr, phent, phnum) = exe_phdrs(); let mut current_phdr = first_phdr.cast::(); + // The dynamic address of the dynamic section, which we can compare with + // the `PT_DYNAMIC` header's static address, if present. + let dynamic_addr: *const c::c_void = unsafe { &_DYNAMIC }; + // SAFETY: We assume the phdr array pointer and length the kernel provided // to the process describe a valid phdr array. unsafe { @@ -34,7 +39,13 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { current_phdr = current_phdr.cast::().add(phent).cast(); match phdr.p_type { - PT_PHDR => base = first_phdr.cast::().sub(phdr.p_vaddr), + // Compute the offset from the static virtual addresses + // in the `p_vaddr` fields to the dynamic addresses. We don't + // always get a `PT_PHDR` or `PT_DYNAMIC` header, so use + // whichever one we get. + PT_PHDR => base = first_phdr.cast::().wrapping_sub(phdr.p_vaddr), + PT_DYNAMIC => base = dynamic_addr.cast::().wrapping_sub(phdr.p_vaddr), + PT_TLS => tls_phdr = phdr, PT_GNU_STACK => stack_size = phdr.p_memsz, _ => {} @@ -51,7 +62,7 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { } } else { StartupTlsInfo { - addr: base.cast::().add((*tls_phdr).p_vaddr).cast(), + addr: base.cast::().wrapping_add((*tls_phdr).p_vaddr).cast(), mem_size: (*tls_phdr).p_memsz, file_size: (*tls_phdr).p_filesz, align: (*tls_phdr).p_align, @@ -61,6 +72,15 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { } } +extern "C" { + /// Declare the `_DYNAMIC` symbol so that we can compare its address with + /// the static address in the `PT_DYNAMIC` header to learn our offset. Use + /// a weak symbol because `_DYNAMIC` is not always present. + static _DYNAMIC: c::c_void; +} +// Rust has `extern_weak` but it isn't stable, so use a `global_asm`. +global_asm!(".weak _DYNAMIC"); + /// The values returned from [`startup_tls_info`]. /// /// [`startup_tls_info`]: crate::runtime::startup_tls_info diff --git a/vendor/rustix/src/backend/linux_raw/shm/mod.rs b/vendor/rustix/src/backend/linux_raw/shm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs new file mode 100644 index 000000000..3b083f4b5 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/syscalls.rs @@ -0,0 +1,47 @@ +use crate::ffi::CStr; + +use crate::backend::fs::syscalls::{open, unlink}; +use crate::backend::fs::types::{Mode, OFlags}; +use crate::fd::OwnedFd; +use crate::io; +use crate::shm::ShmOFlags; + +const NAME_MAX: usize = 255; +const SHM_DIR: &[u8] = b"/dev/shm/"; + +fn get_shm_name(name: &CStr) -> io::Result<([u8; NAME_MAX + SHM_DIR.len() + 1], usize)> { + let name = name.to_bytes(); + + if name.len() > NAME_MAX { + return Err(io::Errno::NAMETOOLONG); + } + + let num_slashes = name.iter().take_while(|x| **x == b'/').count(); + let after_slashes = &name[num_slashes..]; + if after_slashes.is_empty() + || after_slashes == b"." + || after_slashes == b".." + || after_slashes.contains(&b'/') + { + return Err(io::Errno::INVAL); + } + + let mut path = [0; NAME_MAX + SHM_DIR.len() + 1]; + path[..SHM_DIR.len()].copy_from_slice(SHM_DIR); + path[SHM_DIR.len()..SHM_DIR.len() + name.len()].copy_from_slice(name); + Ok((path, SHM_DIR.len() + name.len() + 1)) +} + +pub(crate) fn shm_open(name: &CStr, oflags: ShmOFlags, mode: Mode) -> io::Result { + let (path, len) = get_shm_name(name)?; + open( + CStr::from_bytes_with_nul(&path[..len]).unwrap(), + OFlags::from_bits(oflags.bits()).unwrap() | OFlags::CLOEXEC, + mode, + ) +} + +pub(crate) fn shm_unlink(name: &CStr) -> io::Result<()> { + let (path, len) = get_shm_name(name)?; + unlink(CStr::from_bytes_with_nul(&path[..len]).unwrap()) +} diff --git a/vendor/rustix/src/backend/linux_raw/shm/types.rs b/vendor/rustix/src/backend/linux_raw/shm/types.rs new file mode 100644 index 000000000..3343d4424 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/shm/types.rs @@ -0,0 +1,30 @@ +use crate::backend::c; +use bitflags::bitflags; + +bitflags! { + /// `O_*` constants for use with [`shm_open`]. + /// + /// [`shm_open`]: crate:shm::shm_open + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct ShmOFlags: c::c_uint { + /// `O_CREAT` + #[doc(alias = "CREAT")] + const CREATE = linux_raw_sys::general::O_CREAT; + + /// `O_EXCL` + const EXCL = linux_raw_sys::general::O_EXCL; + + /// `O_RDONLY` + const RDONLY = linux_raw_sys::general::O_RDONLY; + + /// `O_RDWR` + const RDWR = linux_raw_sys::general::O_RDWR; + + /// `O_TRUNC` + const TRUNC = linux_raw_sys::general::O_TRUNC; + + /// + const _ = !0; + } +} diff --git a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs index 947d5168e..6b41cdbab 100644 --- a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs @@ -6,9 +6,10 @@ #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] use super::types::RawUname; -use crate::backend::conv::{ret, ret_infallible, slice}; +use crate::backend::c; +use crate::backend::conv::{c_int, ret, ret_infallible, slice}; use crate::io; -use crate::system::Sysinfo; +use crate::system::{RebootCommand, Sysinfo}; use core::mem::MaybeUninit; #[inline] @@ -34,3 +35,15 @@ pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { let (ptr, len) = slice(name); unsafe { ret(syscall_readonly!(__NR_sethostname, ptr, len)) } } + +#[inline] +pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_reboot, + c_int(c::LINUX_REBOOT_MAGIC1), + c_int(c::LINUX_REBOOT_MAGIC2), + c_int(cmd as i32) + )) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs index 09100441f..d2fe91236 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -37,8 +37,46 @@ pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result { pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result { unsafe { let mut result = MaybeUninit::::uninit(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so zero out the fields ourselves. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + { + result.write(core::mem::zeroed()); + } + ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result))?; - Ok(result.assume_init()) + + let result = result.assume_init(); + + // QEMU's `TCGETS2` doesn't currently set `input_speed` or + // `output_speed` on PowerPC, so set them manually if we can. + #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] + let result = { + use crate::termios::speed; + let mut result = result; + if result.output_speed == 0 && (result.control_modes.bits() & c::CBAUD) != c::BOTHER { + if let Some(output_speed) = speed::decode(result.control_modes.bits() & c::CBAUD) { + result.output_speed = output_speed; + } + } + if result.input_speed == 0 + && ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) != c::BOTHER + { + // For input speeds, `B0` is special-cased to mean the input + // speed is the same as the output speed. + if ((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) == c::B0 { + result.input_speed = result.output_speed; + } else if let Some(input_speed) = + speed::decode((result.control_modes.bits() & c::CIBAUD) >> c::IBSHIFT) + { + result.input_speed = input_speed; + } + } + result + }; + + Ok(result) } } @@ -240,7 +278,7 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit]) -> io::Re // Check that `fd` is really a tty. tcgetwinsize(fd)?; - // Get a fd to '/proc/self/fd'. + // Get a fd to "/proc/self/fd". let proc_self_fd = procfs::proc_self_fd()?; // Gather the ttyname by reading the "fd" file inside `proc_self_fd`. diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs index ab43aed7c..f3e653b0a 100644 --- a/vendor/rustix/src/backend/linux_raw/time/types.rs +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -21,7 +21,7 @@ bitflags! { /// `TFD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; - /// + /// const _ = !0; } } @@ -39,7 +39,7 @@ bitflags! { /// `TFD_TIMER_CANCEL_ON_SET` const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; - /// + /// const _ = !0; } } diff --git a/vendor/rustix/src/backend/linux_raw/vdso.rs b/vendor/rustix/src/backend/linux_raw/vdso.rs index 1b0ae5375..102fa6b38 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso.rs @@ -55,7 +55,7 @@ fn elf_hash(name: &CStr) -> u32 { /// Create a `Vdso` value by parsing the vDSO at the `sysinfo_ehdr` address. fn init_from_sysinfo_ehdr() -> Option { - // SAFETY: the auxv initialization code does extensive checks to ensure + // SAFETY: The auxv initialization code does extensive checks to ensure // that the value we get really is an `AT_SYSINFO_EHDR` value from the // kernel. unsafe { @@ -106,9 +106,9 @@ fn init_from_sysinfo_ehdr() -> Option { vdso.load_end = vdso.base_plus(phdr.p_offset.checked_add(phdr.p_memsz)?)?; vdso.pv_offset = phdr.p_offset.wrapping_sub(phdr.p_vaddr); } else if phdr.p_type == PT_DYNAMIC { - // If `p_offset` is zero, it's more likely that we're looking at memory - // that has been zeroed than that the kernel has somehow aliased the - // `Ehdr` and the `Elf_Dyn` array. + // If `p_offset` is zero, it's more likely that we're looking + // at memory that has been zeroed than that the kernel has + // somehow aliased the `Ehdr` and the `Elf_Dyn` array. if phdr.p_offset < size_of::() { return None; } @@ -117,9 +117,9 @@ fn init_from_sysinfo_ehdr() -> Option { .as_ptr(); num_dyn = phdr.p_memsz / size_of::(); } else if phdr.p_type == PT_INTERP || phdr.p_type == PT_GNU_RELRO { - // Don't trust any ELF image that has an “interpreter” or that uses - // RELRO, which is likely to be a user ELF image rather and not the - // kernel vDSO. + // Don't trust any ELF image that has an “interpreter” or + // that uses RELRO, which is likely to be a user ELF image + // rather and not the kernel vDSO. return None; } } @@ -176,8 +176,8 @@ fn init_from_sysinfo_ehdr() -> Option { } i = i.checked_add(1)?; } - // The upstream code checks `symstrings`, `symtab`, and `hash` for null; - // here, `check_raw_pointer` has already done that. + // The upstream code checks `symstrings`, `symtab`, and `hash` for + // null; here, `check_raw_pointer` has already done that. if vdso.verdef.is_null() { vdso.versym = null(); diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs index 1ff50415b..601dc1855 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs @@ -36,8 +36,8 @@ use { #[inline] pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. + // function with an ABI like libc `clock_gettime`, and calling it has the + // side effect of writing to the result buffer, and no others. unsafe { let mut result = MaybeUninit::<__kernel_timespec>::uninit(); let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { @@ -78,8 +78,8 @@ pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Resu }; // SAFETY: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. + // function with an ABI like libc `clock_gettime`, and calling it has the + // side effect of writing to the result buffer, and no others. unsafe { const EINVAL: c::c_int = -(c::EINVAL as c::c_int); let mut timespec = MaybeUninit::::uninit(); @@ -234,8 +234,8 @@ pub(super) type SyscallType = unsafe extern "C" fn(); #[cold] fn init_clock_gettime() -> ClockGettimeType { init(); - // SAFETY: Load the function address from static storage that we - // just initialized. + // SAFETY: Load the function address from static storage that we just + // initialized. unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } } @@ -244,8 +244,8 @@ fn init_clock_gettime() -> ClockGettimeType { #[cold] fn init_syscall() -> SyscallType { init(); - // SAFETY: Load the function address from static storage that we - // just initialized. + // SAFETY: Load the function address from static storage that we just + // initialized. unsafe { transmute(SYSCALL.load(Relaxed)) } } @@ -318,7 +318,7 @@ unsafe fn _rustix_clock_gettime_via_syscall( #[cfg(target_arch = "x86")] extern "C" { /// A symbol pointing to an `int 0x80` instruction. This “function” is only - /// called from assembly, and only with the x86 syscall calling convention. + /// called from assembly, and only with the x86 syscall calling convention, /// so its signature here is not its true signature. /// /// This extern block and the `global_asm!` below can be replaced with @@ -345,9 +345,9 @@ rustix_int_0x80: fn minimal_init() { // SAFETY: Store default function addresses in static storage so that if we - // end up making any system calls while we read the vDSO, they'll work. - // If the memory happens to already be initialized, this is redundant, but - // not harmful. + // end up making any system calls while we read the vDSO, they'll work. If + // the memory happens to already be initialized, this is redundant, but not + // harmful. unsafe { #[cfg(feature = "time")] { @@ -381,9 +381,9 @@ fn init() { if let Some(vdso) = vdso::Vdso::new() { #[cfg(feature = "time")] { - // Look up the platform-specific `clock_gettime` symbol as documented - // [here], except on 32-bit platforms where we look up the - // `64`-suffixed variant and fail if we don't find it. + // Look up the platform-specific `clock_gettime` symbol as + // documented [here], except on 32-bit platforms where we look up + // the `64`-suffixed variant and fail if we don't find it. // // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html #[cfg(target_arch = "x86_64")] @@ -408,8 +408,8 @@ fn init() { #[cfg(target_pointer_width = "64")] let ok = true; - // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are not - // available on older kernel versions. + // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are + // not available on older kernel versions. #[cfg(any( target_arch = "arm", target_arch = "mips", @@ -421,9 +421,9 @@ fn init() { if ok { assert!(!ptr.is_null()); - // SAFETY: Store the computed function addresses in static storage - // so that we don't need to compute it again (but if we do, it - // doesn't hurt anything). + // SAFETY: Store the computed function addresses in static + // storage so that we don't need to compute it again (but if + // we do, it doesn't hurt anything). unsafe { CLOCK_GETTIME.store(ptr.cast(), Relaxed); } -- cgit v1.2.3