Commit 07c99001 authored by Eric Biggers's avatar Eric Biggers
Browse files

fs-verity: support reading signature with ioctl

Add support for FS_VERITY_METADATA_TYPE_SIGNATURE to
FS_IOC_READ_VERITY_METADATA.  This allows a userspace server program to
retrieve the built-in signature (if present) of a verity file for
serving to a client which implements fs-verity compatible verification.
See the patch which introduced FS_IOC_READ_VERITY_METADATA for more
details.

The ability for userspace to read the built-in signatures is also useful
because it allows a system that is using the in-kernel signature
verification to migrate to userspace signature verification.

This has been tested using a new xfstest which calls this ioctl via a
new subcommand for the 'fsverity' program from fsverity-utils.

Link: https://lore.kernel.org/r/20210115181819.34732-7-ebiggers@kernel.org


Reviewed-by: default avatarVictor Hsieh <victorhsieh@google.com>
Reviewed-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 947191ac
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ This ioctl takes in a pointer to the following structure::

   #define FS_VERITY_METADATA_TYPE_MERKLE_TREE     1
   #define FS_VERITY_METADATA_TYPE_DESCRIPTOR      2
   #define FS_VERITY_METADATA_TYPE_SIGNATURE       3

   struct fsverity_read_metadata_arg {
           __u64 metadata_type;
@@ -256,6 +257,10 @@ This ioctl takes in a pointer to the following structure::
- ``FS_VERITY_METADATA_TYPE_DESCRIPTOR`` reads the fs-verity
  descriptor.  See `fs-verity descriptor`_.

- ``FS_VERITY_METADATA_TYPE_SIGNATURE`` reads the signature which was
  passed to FS_IOC_ENABLE_VERITY, if any.  See `Built-in signature
  verification`_.

The semantics are similar to those of ``pread()``.  ``offset``
specifies the offset in bytes into the metadata item to read from, and
``length`` specifies the maximum number of bytes to read from the
@@ -279,7 +284,9 @@ FS_IOC_READ_VERITY_METADATA can fail with the following errors:
- ``EINTR``: the ioctl was interrupted before any data was read
- ``EINVAL``: reserved fields were set, or ``offset + length``
  overflowed
- ``ENODATA``: the file is not a verity file
- ``ENODATA``: the file is not a verity file, or
  FS_VERITY_METADATA_TYPE_SIGNATURE was requested but the file doesn't
  have a built-in signature
- ``ENOTTY``: this type of filesystem does not implement fs-verity, or
  this ioctl is not yet implemented on it
- ``EOPNOTSUPP``: the kernel was not configured with fs-verity
+30 −0
Original line number Diff line number Diff line
@@ -114,6 +114,34 @@ static int fsverity_read_descriptor(struct inode *inode,
	kfree(desc);
	return res;
}

static int fsverity_read_signature(struct inode *inode,
				   void __user *buf, u64 offset, int length)
{
	struct fsverity_descriptor *desc;
	size_t desc_size;
	int res;

	res = fsverity_get_descriptor(inode, &desc, &desc_size);
	if (res)
		return res;

	if (desc->sig_size == 0) {
		res = -ENODATA;
		goto out;
	}

	/*
	 * Include only the signature.  Note that fsverity_get_descriptor()
	 * already verified that sig_size is in-bounds.
	 */
	res = fsverity_read_buffer(buf, offset, length, desc->signature,
				   le32_to_cpu(desc->sig_size));
out:
	kfree(desc);
	return res;
}

/**
 * fsverity_ioctl_read_metadata() - read verity metadata from a file
 * @filp: file to read the metadata from
@@ -158,6 +186,8 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg)
						 length);
	case FS_VERITY_METADATA_TYPE_DESCRIPTOR:
		return fsverity_read_descriptor(inode, buf, arg.offset, length);
	case FS_VERITY_METADATA_TYPE_SIGNATURE:
		return fsverity_read_signature(inode, buf, arg.offset, length);
	default:
		return -EINVAL;
	}
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct fsverity_formatted_digest {

#define FS_VERITY_METADATA_TYPE_MERKLE_TREE	1
#define FS_VERITY_METADATA_TYPE_DESCRIPTOR	2
#define FS_VERITY_METADATA_TYPE_SIGNATURE	3

struct fsverity_read_metadata_arg {
	__u64 metadata_type;