diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/rustix/src/backend/linux_raw/termios | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/termios')
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/termios/mod.rs | 2 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/termios/syscalls.rs | 425 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/linux_raw/termios/types.rs | 13 |
3 files changed, 0 insertions, 440 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/termios/mod.rs b/vendor/rustix/src/backend/linux_raw/termios/mod.rs deleted file mode 100644 index 1e0181a9..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs deleted file mode 100644 index 07c3a3d9..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ /dev/null @@ -1,425 +0,0 @@ -//! linux_raw syscalls supporting `rustix::termios`. -//! -//! # 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_ref, c_uint, ret}; -use crate::fd::BorrowedFd; -#[cfg(feature = "alloc")] -use crate::ffi::CStr; -use crate::io; -use crate::pid::Pid; -use crate::termios::{ - speed, Action, ControlModes, InputModes, LocalModes, OptionalActions, OutputModes, - QueueSelector, SpecialCodeIndex, Termios, Winsize, -}; -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -use crate::{fs::FileType, path::DecInt}; -use core::mem::MaybeUninit; - -#[inline] -pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { - unsafe { - let mut result = MaybeUninit::<Winsize>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGWINSZ), &mut result))?; - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { - let mut result = MaybeUninit::<Termios>::uninit(); - - // SAFETY: This invokes the `TCGETS2` ioctl, which initializes the full - // `Termios` structure. - unsafe { - match ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result)) { - Ok(()) => Ok(result.assume_init()), - - // A `NOTTY` or `ACCESS` might mean the OS doesn't support - // `TCGETS2`, for example a seccomp environment or WSL that only - // knows about `TCGETS`. Fall back to the old `TCGETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => tcgetattr_fallback(fd), - - Err(err) => Err(err), - } - } -} - -/// Implement `tcgetattr` using the old `TCGETS` ioctl. -#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] -#[cold] -fn tcgetattr_fallback(fd: BorrowedFd<'_>) -> io::Result<Termios> { - use core::ptr::{addr_of, addr_of_mut}; - - let mut result = MaybeUninit::<Termios>::uninit(); - - // SAFETY: This invokes the `TCGETS` ioctl which initializes the `Termios` - // structure except for the `input_speed` and `output_speed` fields, which - // we manually initialize before forming a reference to the full `Termios`. - unsafe { - // Do the old `TCGETS` call. - ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS), &mut result))?; - - // Read the `control_modes` field without forming a reference to the - // `Termios` because it isn't fully initialized yet. - let ptr = result.as_mut_ptr(); - let control_modes = addr_of!((*ptr).control_modes).read(); - - // Infer the output speed and set `output_speed`. - let encoded_out = control_modes.bits() & c::CBAUD; - let output_speed = match speed::decode(encoded_out) { - Some(output_speed) => output_speed, - None => return Err(io::Errno::RANGE), - }; - addr_of_mut!((*ptr).output_speed).write(output_speed); - - // Infer the input speed and set `input_speed`. `B0` is a special-case - // that means the input speed is the same as the output speed. - let encoded_in = (control_modes.bits() & c::CIBAUD) >> c::IBSHIFT; - let input_speed = if encoded_in == c::B0 { - output_speed - } else { - match speed::decode(encoded_in) { - Some(input_speed) => input_speed, - None => return Err(io::Errno::RANGE), - } - }; - addr_of_mut!((*ptr).input_speed).write(input_speed); - - // Now all the fields are set. - Ok(result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let mut result = MaybeUninit::<c::pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGPGRP), &mut result))?; - let pid = result.assume_init(); - - // This doesn't appear to be documented, but it appears `tcsetpgrp` can - // succeed and set the pid to 0 if we pass it a pseudo-terminal device - // fd. For now, fail with `OPNOTSUPP`. - if pid == 0 { - return Err(io::Errno::OPNOTSUPP); - } - - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn tcsetattr( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - // Translate from `optional_actions` into a `TCSETS2` ioctl request code. - // On MIPS, `optional_actions` has `TCSETS` added to it. - let request = c::TCSETS2 - + if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as u32 - c::TCSETS - } else { - optional_actions as u32 - }; - - // SAFETY: This invokes the `TCSETS2` ioctl. - unsafe { - match ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(request), - by_ref(termios) - )) { - Ok(()) => Ok(()), - - // Similar to `tcgetattr_fallback`, `NOTTY` or `ACCESS` might mean - // the OS doesn't support `TCSETS2`. Fall back to the old `TCSETS`. - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] - Err(io::Errno::NOTTY) | Err(io::Errno::ACCESS) => { - tcsetattr_fallback(fd, optional_actions, termios) - } - - Err(err) => Err(err), - } - } -} - -/// Implement `tcsetattr` using the old `TCSETS` ioctl. -#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] -#[cold] -fn tcsetattr_fallback( - fd: BorrowedFd<'_>, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - // `TCSETS` silently accepts `BOTHER` in `c_cflag` even though it doesn't - // read `c_ispeed`/`c_ospeed`, so detect this case and fail if needed. - let control_modes_bits = termios.control_modes.bits(); - let encoded_out = control_modes_bits & c::CBAUD; - let encoded_in = (control_modes_bits & c::CIBAUD) >> c::IBSHIFT; - if encoded_out == c::BOTHER || encoded_in == c::BOTHER { - return Err(io::Errno::RANGE); - } - - // Translate from `optional_actions` into a `TCSETS` ioctl request code. On - // MIPS, `optional_actions` already has `TCSETS` added to it. - let request = if cfg!(any( - target_arch = "mips", - target_arch = "mips32r6", - target_arch = "mips64", - target_arch = "mips64r6" - )) { - optional_actions as u32 - } else { - optional_actions as u32 + c::TCSETS - }; - - // SAFETY: This invokes the `TCSETS` ioctl. - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(request), - by_ref(termios) - )) - } -} - -#[inline] -pub(crate) fn tcsendbreak(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCSBRK), - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn tcdrain(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCSBRK), - c_uint(1) - )) - } -} - -#[inline] -pub(crate) fn tcflush(fd: BorrowedFd<'_>, queue_selector: QueueSelector) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCFLSH), - c_uint(queue_selector as u32) - )) - } -} - -#[inline] -pub(crate) fn tcflow(fd: BorrowedFd<'_>, action: Action) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TCXONC), - c_uint(action as u32) - )) - } -} - -#[inline] -pub(crate) fn tcgetsid(fd: BorrowedFd<'_>) -> io::Result<Pid> { - unsafe { - let mut result = MaybeUninit::<c::pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(c::TIOCGSID), &mut result))?; - let pid = result.assume_init(); - Ok(Pid::from_raw_unchecked(pid)) - } -} - -#[inline] -pub(crate) fn tcsetwinsize(fd: BorrowedFd<'_>, winsize: Winsize) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TIOCSWINSZ), - by_ref(&winsize) - )) - } -} - -#[inline] -pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - let raw_pid: c::c_int = pid.as_raw_nonzero().get(); - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(c::TIOCSPGRP), - by_ref(&raw_pid) - )) - } -} - -/// A wrapper around a conceptual `cfsetspeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD | c::CIBAUD); - termios.control_modes |= - ControlModes::from_bits_retain(encoded_speed | (encoded_speed << c::IBSHIFT)); - - termios.input_speed = arbitrary_speed; - termios.output_speed = arbitrary_speed; - - Ok(()) -} - -/// A wrapper around a conceptual `cfsetospeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_output_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed); - - termios.output_speed = arbitrary_speed; - - Ok(()) -} - -/// A wrapper around a conceptual `cfsetispeed` which handles an arbitrary -/// integer speed value. -#[inline] -pub(crate) fn set_input_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { - let encoded_speed = speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - - debug_assert_eq!(encoded_speed & !c::CBAUD, 0); - - termios.control_modes -= ControlModes::from_bits_retain(c::CIBAUD); - termios.control_modes |= ControlModes::from_bits_retain(encoded_speed << c::IBSHIFT); - - termios.input_speed = arbitrary_speed; - - Ok(()) -} - -#[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - // From the Linux [`cfmakeraw` manual page]: - // - // [`cfmakeraw` manual page]: https://man7.org/linux/man-pages/man3/cfmakeraw.3.html - termios.input_modes -= InputModes::IGNBRK - | InputModes::BRKINT - | InputModes::PARMRK - | InputModes::ISTRIP - | InputModes::INLCR - | InputModes::IGNCR - | InputModes::ICRNL - | InputModes::IXON; - termios.output_modes -= OutputModes::OPOST; - termios.local_modes -= LocalModes::ECHO - | LocalModes::ECHONL - | LocalModes::ICANON - | LocalModes::ISIG - | LocalModes::IEXTEN; - termios.control_modes -= ControlModes::CSIZE | ControlModes::PARENB; - termios.control_modes |= ControlModes::CS8; - - // Musl and glibc also do these: - termios.special_codes[SpecialCodeIndex::VMIN] = 1; - termios.special_codes[SpecialCodeIndex::VTIME] = 0; -} - -#[inline] -pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { - // On error, Linux will return either `EINVAL` (2.6.32) or `ENOTTY` - // (otherwise), because we assume we're never passing an invalid - // file descriptor (which would get `EBADF`). Either way, an error - // means we don't have a tty. - tcgetwinsize(fd).is_ok() -} - -#[cfg(feature = "alloc")] -#[cfg(feature = "fs")] -pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { - let fd_stat = crate::backend::fs::syscalls::fstat(fd)?; - - // Quick check: if `fd` isn't a character device, it's not a tty. - if FileType::from_raw_mode(fd_stat.st_mode) != FileType::CharacterDevice { - return Err(io::Errno::NOTTY); - } - - // Check that `fd` is really a tty. - tcgetwinsize(fd)?; - - // Create the "/proc/self/fd/<fd>" string. - let mut proc_self_fd_buf: [u8; 25] = *b"/proc/self/fd/\0\0\0\0\0\0\0\0\0\0\0"; - let dec_int = DecInt::from_fd(fd); - let bytes_with_nul = dec_int.as_bytes_with_nul(); - proc_self_fd_buf[b"/proc/self/fd/".len()..][..bytes_with_nul.len()] - .copy_from_slice(bytes_with_nul); - - // SAFETY: We just wrote a valid C String. - let proc_self_fd_path = unsafe { CStr::from_ptr(proc_self_fd_buf.as_ptr().cast()) }; - - let ptr = buf.as_mut_ptr(); - let len = { - // Gather the ttyname by reading the "fd" file inside `proc_self_fd`. - let (init, uninit) = crate::fs::readlinkat_raw(crate::fs::CWD, proc_self_fd_path, buf)?; - - // If the number of bytes is equal to the buffer length, truncation may - // have occurred. This check also ensures that we have enough space for - // adding a NUL terminator. - if uninit.is_empty() { - return Err(io::Errno::RANGE); - } - - // `readlinkat` returns the number of bytes placed in the buffer. - // NUL-terminate the string at that offset. - uninit[0].write(b'\0'); - - init.len() - }; - - // Check that the path we read refers to the same file as `fd`. - { - // SAFETY: We just wrote the NUL byte above. - let path = unsafe { CStr::from_ptr(ptr.cast()) }; - - let path_stat = crate::backend::fs::syscalls::stat(path)?; - if path_stat.st_dev != fd_stat.st_dev || path_stat.st_ino != fd_stat.st_ino { - return Err(io::Errno::NODEV); - } - } - - // Return the length, excluding the NUL terminator. - Ok(len) -} diff --git a/vendor/rustix/src/backend/linux_raw/termios/types.rs b/vendor/rustix/src/backend/linux_raw/termios/types.rs deleted file mode 100644 index a8aaee39..00000000 --- a/vendor/rustix/src/backend/linux_raw/termios/types.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Types for the `termios` module. - -#![allow(non_camel_case_types)] - -use crate::ffi; - -// We don't want to use `tcflag_t` directly so we don't expose linux_raw_sys -// publicly. It appears to be `c_ulong `on SPARC and `c_uint` everywhere else. - -#[cfg(target_arch = "sparc")] -pub type tcflag_t = ffi::c_ulong; -#[cfg(not(target_arch = "sparc"))] -pub type tcflag_t = ffi::c_uint; |
