From dc82c819f6cd9b28eb825ff2f586e3d1814d486d Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Thu, 25 Jun 2020 14:00:42 +0900 Subject: [PATCH] devices: fs: Implement FS_IOC_FSSETXATTR Needed by arcvm. BUG=b:159297591 TEST=run a test program that calls the ioctl Change-Id: I1f8c17fa2b2457f5a9e73045c3dbee3440eb943d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2265932 Auto-Submit: Chirantan Ekbote Reviewed-by: Daniel Verkamp Tested-by: Chirantan Ekbote Commit-Queue: Chirantan Ekbote --- devices/src/virtio/fs/passthrough.rs | 29 ++++++++++++++++++++++++++++ seccomp/aarch64/fs_device.policy | 2 +- seccomp/arm/fs_device.policy | 2 +- seccomp/x86_64/fs_device.policy | 2 +- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index b9ebfafbca..d5628eb636 100644 --- a/devices/src/virtio/fs/passthrough.rs +++ b/devices/src/virtio/fs/passthrough.rs @@ -64,6 +64,7 @@ struct fsxattr { unsafe impl DataInit for fsxattr {} ioctl_ior_nr!(FS_IOC_FSGETXATTR, 'X' as u32, 31, fsxattr); +ioctl_iow_nr!(FS_IOC_FSSETXATTR, 'X' as u32, 32, fsxattr); type Inode = u64; type Handle = u64; @@ -797,6 +798,26 @@ impl PassthroughFs { Ok(IoctlReply::Done(Ok(xattr.as_slice().to_vec()))) } } + + fn set_fsxattr(&self, handle: Handle, r: R) -> io::Result { + let data = self + .handles + .lock() + .get(&handle) + .map(Arc::clone) + .ok_or_else(ebadf)?; + + let attr = fsxattr::from_reader(r)?; + let file = data.file.lock(); + + // Safe because this doesn't modify any memory and we check the return value. + let res = unsafe { ioctl_with_ptr(&*file, FS_IOC_FSSETXATTR(), &attr) }; + if res < 0 { + Ok(IoctlReply::Done(Err(io::Error::last_os_error()))) + } else { + Ok(IoctlReply::Done(Ok(Vec::new()))) + } + } } fn forget_one( @@ -2011,6 +2032,7 @@ impl FileSystem for PassthroughFs { const GET_ENCRYPTION_POLICY: u32 = FS_IOC_GET_ENCRYPTION_POLICY() as u32; const SET_ENCRYPTION_POLICY: u32 = FS_IOC_SET_ENCRYPTION_POLICY() as u32; const GET_FSXATTR: u32 = FS_IOC_FSGETXATTR() as u32; + const SET_FSXATTR: u32 = FS_IOC_FSSETXATTR() as u32; // Normally, we wouldn't need to retry the FS_IOC_GET_ENCRYPTION_POLICY and // FS_IOC_SET_ENCRYPTION_POLICY ioctls. Unfortunately, the I/O directions for both of them @@ -2047,6 +2069,13 @@ impl FileSystem for PassthroughFs { self.get_fsxattr(handle) } } + SET_FSXATTR => { + if in_size < size_of::() as u32 { + Err(io::Error::from_raw_os_error(libc::EINVAL)) + } else { + self.set_fsxattr(handle, r) + } + } _ => Err(io::Error::from_raw_os_error(libc::ENOTTY)), } } diff --git a/seccomp/aarch64/fs_device.policy b/seccomp/aarch64/fs_device.policy index 61006485bc..52b1e8e27c 100644 --- a/seccomp/aarch64/fs_device.policy +++ b/seccomp/aarch64/fs_device.policy @@ -22,7 +22,7 @@ ftruncate: 1 getdents64: 1 getegid: 1 geteuid: 1 -ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR +ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR || arg1 == FS_IOC_FSSETXATTR linkat: 1 lseek: 1 mkdirat: 1 diff --git a/seccomp/arm/fs_device.policy b/seccomp/arm/fs_device.policy index 291d9f4274..1bc35fe007 100644 --- a/seccomp/arm/fs_device.policy +++ b/seccomp/arm/fs_device.policy @@ -22,7 +22,7 @@ ftruncate64: 1 getdents64: 1 getegid32: 1 geteuid32: 1 -ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR +ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR || arg1 == FS_IOC_FSSETXATTR linkat: 1 _llseek: 1 mkdir: 1 diff --git a/seccomp/x86_64/fs_device.policy b/seccomp/x86_64/fs_device.policy index 12f9bcd1c9..884470ad91 100644 --- a/seccomp/x86_64/fs_device.policy +++ b/seccomp/x86_64/fs_device.policy @@ -21,7 +21,7 @@ ftruncate: 1 getdents64: 1 getegid: 1 geteuid: 1 -ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR +ioctl: arg1 == FS_IOC_GET_ENCRYPTION_POLICY || arg1 == FS_IOC_SET_ENCRYPTION_POLICY || arg1 == FS_IOC_FSGETXATTR || arg1 == FS_IOC_FSSETXATTR linkat: 1 lseek: 1 mkdir: 1