diff --git a/cap-primitives/src/rustix/fs/errors.rs b/cap-primitives/src/rustix/fs/errors.rs index 5748f7ea..8a9de56f 100644 --- a/cap-primitives/src/rustix/fs/errors.rs +++ b/cap-primitives/src/rustix/fs/errors.rs @@ -1,5 +1,6 @@ use std::io; +#[cfg(any(target_os = "android", target_os = "linux"))] #[cold] pub(crate) fn invalid_flags() -> io::Error { rustix::io::Errno::INVAL.into() diff --git a/cap-primitives/src/rustix/fs/permissions_ext.rs b/cap-primitives/src/rustix/fs/permissions_ext.rs index ffbec959..a84ed905 100644 --- a/cap-primitives/src/rustix/fs/permissions_ext.rs +++ b/cap-primitives/src/rustix/fs/permissions_ext.rs @@ -16,7 +16,7 @@ impl PermissionsExt { pub(crate) fn from_std(std: fs::Permissions) -> Self { use std::os::unix::fs::PermissionsExt; Self { - mode: std.mode() as RawMode & 0o7777, + mode: std.mode() as RawMode, } } @@ -26,9 +26,7 @@ impl PermissionsExt { pub(crate) const fn from_raw_mode(mode: RawMode) -> Permissions { Permissions { readonly: Self::readonly(mode), - ext: Self { - mode: mode & 0o7777, - }, + ext: Self { mode }, } } diff --git a/cap-primitives/src/rustix/fs/set_permissions_impl.rs b/cap-primitives/src/rustix/fs/set_permissions_impl.rs index 1ccf08f7..736e8d06 100644 --- a/cap-primitives/src/rustix/fs/set_permissions_impl.rs +++ b/cap-primitives/src/rustix/fs/set_permissions_impl.rs @@ -1,4 +1,4 @@ -use crate::fs::{errors, open, OpenOptions, Permissions}; +use crate::fs::{open, OpenOptions, Permissions}; use rustix::fs::{fchmod, Mode}; use rustix::io::Errno; use std::convert::TryInto; @@ -43,8 +43,8 @@ pub(crate) fn set_permissions_impl( } pub(crate) fn set_file_permissions(file: &fs::File, perm: fs::Permissions) -> io::Result<()> { - #[allow(clippy::useless_conversion)] - let mode = - Mode::from_bits(perm.mode().try_into().unwrap()).ok_or_else(errors::invalid_flags)?; + // Use `from_bits_truncate` for compatibility with std, which allows + // non-permission bits to propagate through. + let mode = Mode::from_bits_truncate(perm.mode().try_into().unwrap()); Ok(fchmod(file, mode)?) } diff --git a/cap-primitives/src/rustix/linux/fs/set_permissions_impl.rs b/cap-primitives/src/rustix/linux/fs/set_permissions_impl.rs index 0436e755..e799bb43 100644 --- a/cap-primitives/src/rustix/linux/fs/set_permissions_impl.rs +++ b/cap-primitives/src/rustix/linux/fs/set_permissions_impl.rs @@ -1,5 +1,5 @@ use super::procfs::set_permissions_through_proc_self_fd; -use crate::fs::{errors, open, OpenOptions, Permissions}; +use crate::fs::{open, OpenOptions, Permissions}; use rustix::fs::{fchmod, Mode, RawMode}; use std::os::unix::fs::PermissionsExt; use std::path::Path; @@ -48,6 +48,8 @@ pub(crate) fn set_permissions_impl( } fn set_file_permissions(file: &fs::File, perm: fs::Permissions) -> io::Result<()> { - let mode = Mode::from_bits(perm.mode() as RawMode).ok_or_else(errors::invalid_flags)?; + // Use `from_bits_truncate` for compatibility with std, which allows + // non-permission bits to propagate through. + let mode = Mode::from_bits_truncate(perm.mode() as RawMode); Ok(fchmod(file, mode)?) } diff --git a/tests/fs_additional.rs b/tests/fs_additional.rs index 0e6fb610..8fa9f875 100644 --- a/tests/fs_additional.rs +++ b/tests/fs_additional.rs @@ -931,9 +931,7 @@ fn check_metadata(std: &std::fs::Metadata, cap: &cap_std::fs::Metadata) { #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; - // The standard library returns file format bits with `mode()`, whereas - // cap-std currently doesn't. - assert_eq!(std.permissions().mode() & 0o7777, cap.permissions().mode()); + assert_eq!(std.permissions().mode(), cap.permissions().mode()); } // If the standard library supports file modified/accessed/created times,