sys: make xattr CStrs constants, repalce c_str! macro

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2024-06-20 10:39:14 +02:00
parent 0233c8c63b
commit b16922860a
3 changed files with 36 additions and 34 deletions

View File

@ -6,30 +6,35 @@ use std::os::unix::io::RawFd;
use nix::errno::Errno;
use proxmox_io::vec;
use proxmox_lang::c_str;
/// `"security.capability"` as a CStr to avoid typos.
///
/// This cannot be `const` until `const_cstr_unchecked` is stable.
pub const XATTR_NAME_FCAPS: &CStr = c"security.capability";
/// `"security.capability"` as a CStr to avoid typos.
#[deprecated = "use the XATTR_NAME_FCAPS constant instead"]
#[inline]
pub fn xattr_name_fcaps() -> &'static CStr {
c_str!("security.capability")
pub const fn xattr_name_fcaps() -> &'static CStr {
XATTR_NAME_FCAPS
}
/// `"system.posix_acl_access"` as a CStr to avoid typos.
///
/// This cannot be `const` until `const_cstr_unchecked` is stable.
pub const XATTR_ACL_ACCESS: &CStr = c"system.posix_acl_access";
/// `"system.posix_acl_access"` as a CStr to avoid typos.
#[deprecated = "use the XATTR_ACL_ACCESS constant instead"]
#[inline]
pub fn xattr_acl_access() -> &'static CStr {
c_str!("system.posix_acl_access")
pub const fn xattr_acl_access() -> &'static CStr {
XATTR_ACL_ACCESS
}
/// `"system.posix_acl_default"` as a CStr to avoid typos.
///
/// This cannot be `const` until `const_cstr_unchecked` is stable.
pub const XATTR_ACL_DEFAULT: &CStr = c"system.posix_acl_default";
/// `"system.posix_acl_default"` as a CStr to avoid typos.
#[deprecated = "use the XATTR_ACL_DEFAULT constant instead"]
#[inline]
pub fn xattr_acl_default() -> &'static CStr {
c_str!("system.posix_acl_default")
pub const fn xattr_acl_default() -> &'static CStr {
XATTR_ACL_DEFAULT
}
/// Result of `flistxattr`, allows iterating over the attributes as a list of `&CStr`s.
@ -161,16 +166,16 @@ pub fn fsetxattr(fd: RawFd, name: &CStr, data: &[u8]) -> Result<(), nix::errno::
pub fn fsetxattr_fcaps(fd: RawFd, fcaps: &[u8]) -> Result<(), nix::errno::Errno> {
// TODO casync checks and removes capabilities if they are set
fsetxattr(fd, xattr_name_fcaps(), fcaps)
fsetxattr(fd, XATTR_NAME_FCAPS, fcaps)
}
pub fn is_security_capability(name: &CStr) -> bool {
name.to_bytes() == xattr_name_fcaps().to_bytes()
name.to_bytes() == XATTR_NAME_FCAPS.to_bytes()
}
pub fn is_acl(name: &CStr) -> bool {
name.to_bytes() == xattr_acl_access().to_bytes()
|| name.to_bytes() == xattr_acl_default().to_bytes()
name.to_bytes() == XATTR_ACL_ACCESS.to_bytes()
|| name.to_bytes() == XATTR_ACL_DEFAULT.to_bytes()
}
/// Check if the passed name buffer starts with a valid xattr namespace prefix
@ -196,16 +201,14 @@ mod tests {
use std::ffi::CString;
use proxmox_lang::c_str;
#[test]
fn test_is_valid_xattr_name() {
let too_long = CString::new(vec![b'a'; 265]).unwrap();
assert!(!is_valid_xattr_name(&too_long));
assert!(!is_valid_xattr_name(c_str!("system.attr")));
assert!(is_valid_xattr_name(c_str!("user.attr")));
assert!(is_valid_xattr_name(c_str!("trusted.attr")));
assert!(is_valid_xattr_name(super::xattr_name_fcaps()));
assert!(!is_valid_xattr_name(c"system.attr"));
assert!(is_valid_xattr_name(c"user.attr"));
assert!(is_valid_xattr_name(c"trusted.attr"));
assert!(is_valid_xattr_name(super::XATTR_NAME_FCAPS));
}
}

View File

@ -11,7 +11,7 @@ use nix::sys::stat::Mode;
use nix::unistd::Pid;
use nix::NixPath;
use proxmox_lang::{c_str, error::io_err_other};
use proxmox_lang::error::io_err_other;
use crate::error::SysResult;
use crate::linux::procfs::{MountInfo, PidStat};
@ -108,14 +108,14 @@ impl PidFd {
/// Get the `PidStat` structure for this process. (`/proc/PID/stat`)
pub fn get_stat(&self) -> io::Result<PidStat> {
let data = self.read_file(c_str!("stat"))?;
let data = self.read_file(c"stat")?;
let data = String::from_utf8(data).map_err(io_err_other)?;
PidStat::parse(&data).map_err(io_err_other)
}
/// Read this process' `/proc/PID/mountinfo` file.
pub fn get_mount_info(&self) -> io::Result<MountInfo> {
MountInfo::parse(&self.read_file(c_str!("mountinfo"))?).map_err(io_err_other)
MountInfo::parse(&self.read_file(c"mountinfo")?).map_err(io_err_other)
}
/// Attempt to get a `PidFd` from a raw file descriptor.

View File

@ -4,7 +4,6 @@ use std::path::PathBuf;
use nix::errno::Errno;
use proxmox_lang::c_str;
use proxmox_sys::fs::xattr::{fgetxattr, fsetxattr};
#[test]
@ -20,27 +19,27 @@ fn test_fsetxattr_fgetxattr() {
let fd = file.as_raw_fd();
if let Err(Errno::EOPNOTSUPP) = fsetxattr(fd, c_str!("user.attribute0"), b"value0") {
if let Err(Errno::EOPNOTSUPP) = fsetxattr(fd, c"user.attribute0", b"value0") {
return;
}
assert!(fsetxattr(fd, c_str!("user.attribute0"), b"value0").is_ok());
assert!(fsetxattr(fd, c_str!("user.empty"), b"").is_ok());
assert!(fsetxattr(fd, c"user.attribute0", b"value0").is_ok());
assert!(fsetxattr(fd, c"user.empty", b"").is_ok());
if nix::unistd::Uid::current() != nix::unistd::ROOT {
assert_eq!(
fsetxattr(fd, c_str!("trusted.attribute0"), b"value0"),
fsetxattr(fd, c"trusted.attribute0", b"value0"),
Err(Errno::EPERM)
);
}
let v0 = fgetxattr(fd, c_str!("user.attribute0")).unwrap();
let v1 = fgetxattr(fd, c_str!("user.empty")).unwrap();
let v0 = fgetxattr(fd, c"user.attribute0").unwrap();
let v1 = fgetxattr(fd, c"user.empty").unwrap();
assert_eq!(v0, b"value0".as_ref());
assert_eq!(v1, b"".as_ref());
assert_eq!(
fgetxattr(fd, c_str!("user.attribute1")),
fgetxattr(fd, c"user.attribute1"),
Err(Errno::ENODATA)
);