mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
fsverity: Explicitly require FMODE_READ to retrieve hashes
The comment in fsverity_ioctl_read_metadata(), which justifies not checking for FMODE_READ, doesn't consider that the nonstandard access mode 3 (ioctl-only) exists. Opening an ioctl-only fd generally requires read (and write) permission. However, there are gaps with certain LSMs: an ioctl-only fd requests read (and write) permission via security_inode_permission, but not security_file_open. With certain LSMs relying on the latter, such as Landlock and AppArmor, an ioctl-only fd can be opened without the LSM granting read (and write) permission. Since FS_IOC_READ_VERITY_METADATA returns hashes of file contents blocks, it should require read permission. This also applies to FS_IOC_MEASURE_VERITY, which returns a hash for the whole file. Meanwhile, ioctl-only fds are a rarely-used feature, not known to be used with either ioctl. Therefore, just disallow these ioctls on ioctl-only file descriptors, similar to what was already done with FS_IOC_ENABLE_VERITY. More specifically, explicitly check for FMODE_READ. This also covers write-only fds to non-verity files which otherwise would have failed with ENODATA. This change in error code for write-only fds should be fine too, as these ioctls cannot be usefully used with write-only fds anyway, but it's worth noting as another technicality. Fixes:4dd893d832("fs-verity: implement FS_IOC_MEASURE_VERITY ioctl") Fixes:e17fe6579d("fs-verity: add FS_IOC_READ_VERITY_METADATA ioctl") Cc: stable@vger.kernel.org Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org> Link: https://patch.msgid.link/20261022211522.1489943-1-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org>
This commit is contained in:
parent
8a36f53fd5
commit
1acb4fd2d0
|
|
@ -170,6 +170,7 @@ fatal signal), no changes are made to the file.
|
|||
FS_IOC_ENABLE_VERITY can fail with the following errors:
|
||||
|
||||
- ``EACCES``: the process does not have write access to the file
|
||||
- ``EBADF``: the file descriptor is not open for reading
|
||||
- ``EBADMSG``: the builtin signature is malformed
|
||||
- ``EBUSY``: this ioctl is already running on the file
|
||||
- ``EEXIST``: the file already has verity enabled
|
||||
|
|
@ -232,6 +233,7 @@ regardless of the size of the file.
|
|||
|
||||
FS_IOC_MEASURE_VERITY can fail with the following errors:
|
||||
|
||||
- ``EBADF``: the file descriptor is not open for reading
|
||||
- ``EFAULT``: the caller provided inaccessible memory
|
||||
- ``ENODATA``: the file is not a verity file
|
||||
- ``ENOTTY``: this type of filesystem does not implement fs-verity
|
||||
|
|
@ -310,6 +312,7 @@ blocks from disk without actually verifying the path to the root node.
|
|||
|
||||
FS_IOC_READ_VERITY_METADATA can fail with the following errors:
|
||||
|
||||
- ``EBADF``: the file descriptor is not open for reading
|
||||
- ``EFAULT``: the caller provided inaccessible memory
|
||||
- ``EINTR``: the ioctl was interrupted before any data was read
|
||||
- ``EINVAL``: reserved fields were set, or ``offset + length``
|
||||
|
|
|
|||
|
|
@ -31,6 +31,16 @@ int fsverity_ioctl_measure(struct file *filp, void __user *_uarg)
|
|||
const struct fsverity_hash_alg *hash_alg;
|
||||
struct fsverity_digest arg;
|
||||
|
||||
/*
|
||||
* This ioctl returns a hash of the file contents, so it should require
|
||||
* read permission. Disallow it on ioctl-only (i.e., nonstandard access
|
||||
* mode 3) fds, which can in some cases be acquired without passing all
|
||||
* LSM read-permission checks. Also disallow write-only fds, which can
|
||||
* refer only to non-verity files which would fail with ENODATA anyway.
|
||||
*/
|
||||
if (!(filp->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
|
||||
vi = fsverity_get_info(inode);
|
||||
if (!vi)
|
||||
return -ENODATA; /* not a verity file */
|
||||
|
|
|
|||
|
|
@ -166,13 +166,19 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg)
|
|||
int length;
|
||||
void __user *buf;
|
||||
|
||||
/*
|
||||
* This ioctl returns file contents block hashes, so it should require
|
||||
* read permission. Disallow it on ioctl-only (i.e., nonstandard access
|
||||
* mode 3) fds, which can in some cases be acquired without passing all
|
||||
* LSM read-permission checks. Also disallow write-only fds, which can
|
||||
* refer only to non-verity files which would fail with ENODATA anyway.
|
||||
*/
|
||||
if (!(filp->f_mode & FMODE_READ))
|
||||
return -EBADF;
|
||||
|
||||
vi = fsverity_get_info(inode);
|
||||
if (!vi)
|
||||
return -ENODATA; /* not a verity file */
|
||||
/*
|
||||
* Note that we don't have to explicitly check that the file is open for
|
||||
* reading, since verity files can only be opened for reading.
|
||||
*/
|
||||
|
||||
if (copy_from_user(&arg, uarg, sizeof(arg)))
|
||||
return -EFAULT;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user