Skip to content

Commit

Permalink
fsverity: introduce EnableVerifyError::FilesystemNotSupported error
Browse files Browse the repository at this point in the history
This commit improves the UX of the error reporting when enabling
fs-verity fails because the underlying filesystem does not support
this. Here we currently just error with:
```
Inappropriate ioctl for device"
```
with the new code we error with:
```
Filesystem not supported by fs-verity
```

Note that the test relies on the fact that /dev/shm is not supported
by fs-verity.

Closes: containers#59
  • Loading branch information
mvo5 committed Feb 14, 2025
1 parent a68ac14 commit f6caab6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ zstd = "0.13.2"
[dev-dependencies]
insta = "1.42.0"
similar-asserts = "1.6.0"
test-with = { version = "0.14", default-features = false, features = ["executable"] }
test-with = { version = "0.14", default-features = false, features = ["executable", "runtime"] }

[profile.dev.package.sha2]
# this is *really* slow otherwise
Expand Down
52 changes: 49 additions & 3 deletions src/fsverity/ioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ pub enum MeasureVerityError {
InvalidDigestSize { expected: u16 },
}

/// Enabling fsverity failed.
#[derive(Error, Debug, PartialEq)]
pub enum EnableVerifyError {
#[error("Filesystem not supported by fs-verity")]
FilesystemNotSupported,
#[error("{0}")]
Errno(#[from] rustix::io::Errno),
}

// See /usr/include/linux/fsverity.h
#[repr(C)]
#[derive(Debug)]
Expand All @@ -35,12 +44,16 @@ pub struct FsVerityEnableArg {
// #define FS_IOC_ENABLE_VERITY _IOW('f', 133, struct fsverity_enable_arg)
type FsIocEnableVerity = ioctl::WriteOpcode<b'f', 133, FsVerityEnableArg>;

// ENOTTY 25 Inappropriate ioctl for device
// XXX: should we use an errno crate instead?
static ENOTTY: i32 = 25;

/// Enable fsverity on the target file. This is a thin safe wrapper for the underlying base `ioctl`
/// and hence all constraints apply such as requiring the file descriptor to already be `O_RDONLY`
/// etc.
pub fn fs_ioc_enable_verity<F: AsFd, H: FsVerityHashValue>(fd: F) -> std::io::Result<()> {
pub fn fs_ioc_enable_verity<F: AsFd, H: FsVerityHashValue>(fd: F) -> Result<(), EnableVerifyError> {
unsafe {
ioctl::ioctl(
match ioctl::ioctl(
fd,
ioctl::Setter::<FsIocEnableVerity, FsVerityEnableArg>::new(FsVerityEnableArg {
version: 1,
Expand All @@ -53,7 +66,13 @@ pub fn fs_ioc_enable_verity<F: AsFd, H: FsVerityHashValue>(fd: F) -> std::io::Re
sig_ptr: 0,
__reserved2: [0; 11],
}),
)?;
) {
Err(e) if e.raw_os_error() == ENOTTY => {
return Err(EnableVerifyError::FilesystemNotSupported)
}
Err(e) => return Err(e.into()),
Ok(_) => (),
}
}

Ok(())
Expand Down Expand Up @@ -118,6 +137,10 @@ pub fn fs_ioc_measure_verity<F: AsFd, H: FsVerityHashValue>(
mod tests {
use super::*;
use crate::fsverity::Sha256HashValue;
use rustix::fd::FromRawFd;
use std::mem::ManuallyDrop;
use std::os::fd::OwnedFd;
use tempfile::tempfile_in;

#[test]
fn test_measure_verity_opt() -> anyhow::Result<()> {
Expand All @@ -128,4 +151,27 @@ mod tests {
);
Ok(())
}

#[test_with::path(/dev/shm)]
#[test]
fn test_fs_ioc_enable_verity_wrong_fs() {
let file = tempfile_in("/dev/shm").unwrap();
let fd = OwnedFd::try_from(file).unwrap();
let res = fs_ioc_enable_verity::<&OwnedFd, Sha256HashValue>(&fd);
let err = res.err().unwrap();
assert_eq!(err, EnableVerifyError::FilesystemNotSupported);
assert_eq!(err.to_string(), "Filesystem not supported by fs-verity",);
}

#[test]
fn test_fs_ioc_enable_verity_bad_fd() {
let fd = ManuallyDrop::new(unsafe { OwnedFd::from_raw_fd(123456) });
let res = fs_ioc_enable_verity::<&OwnedFd, Sha256HashValue>(&fd);
let err = res.err().unwrap();
assert_eq!(
err,
EnableVerifyError::Errno(rustix::io::Errno::from_raw_os_error(9))
);
assert_eq!(err.to_string(), "Bad file descriptor (os error 9)",);
}
}

0 comments on commit f6caab6

Please sign in to comment.