summary refs log tree commit diff
path: root/fs/verity/enable.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-07-22 09:26:23 -0700
committerEric Biggers <ebiggers@google.com>2019-08-12 19:33:50 -0700
commit432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6 (patch)
treecfcf57b2bb1fbdb1e9b5739f020b0311405363c0 /fs/verity/enable.c
parentadd890c9f9d2d1d79184ded72f23b37b164fc673 (diff)
downloadlinux-432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6.tar.gz
fs-verity: support builtin file signatures
To meet some users' needs, add optional support for having fs-verity
handle a portion of the authentication policy in the kernel.  An
".fs-verity" keyring is created to which X.509 certificates can be
added; then a sysctl 'fs.verity.require_signatures' can be set to cause
the kernel to enforce that all fs-verity files contain a signature of
their file measurement by a key in this keyring.

See the "Built-in signature verification" section of
Documentation/filesystems/fsverity.rst for the full documentation.

Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Diffstat (limited to 'fs/verity/enable.c')
-rw-r--r--fs/verity/enable.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/verity/enable.c b/fs/verity/enable.c
index df5dab03f0c2..eabc6ac19906 100644
--- a/fs/verity/enable.c
+++ b/fs/verity/enable.c
@@ -161,7 +161,7 @@ static int enable_verity(struct file *filp,
 	const struct fsverity_operations *vops = inode->i_sb->s_vop;
 	struct merkle_tree_params params = { };
 	struct fsverity_descriptor *desc;
-	size_t desc_size = sizeof(*desc);
+	size_t desc_size = sizeof(*desc) + arg->sig_size;
 	struct fsverity_info *vi;
 	int err;
 
@@ -183,6 +183,16 @@ static int enable_verity(struct file *filp,
 	}
 	desc->salt_size = arg->salt_size;
 
+	/* Get the signature if the user provided one */
+	if (arg->sig_size &&
+	    copy_from_user(desc->signature,
+			   (const u8 __user *)(uintptr_t)arg->sig_ptr,
+			   arg->sig_size)) {
+		err = -EFAULT;
+		goto out;
+	}
+	desc->sig_size = cpu_to_le32(arg->sig_size);
+
 	desc->data_size = cpu_to_le64(inode->i_size);
 
 	/* Prepare the Merkle tree parameters */
@@ -238,6 +248,10 @@ static int enable_verity(struct file *filp,
 		goto rollback;
 	}
 
+	if (arg->sig_size)
+		pr_debug("Storing a %u-byte PKCS#7 signature alongside the file\n",
+			 arg->sig_size);
+
 	/*
 	 * Tell the filesystem to finish enabling verity on the file.
 	 * Serialized with ->begin_enable_verity() by the inode lock.
@@ -304,8 +318,8 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
 	if (arg.salt_size > FIELD_SIZEOF(struct fsverity_descriptor, salt))
 		return -EMSGSIZE;
 
-	if (arg.sig_size)
-		return -EINVAL;
+	if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE)
+		return -EMSGSIZE;
 
 	/*
 	 * Require a regular file with write access.  But the actual fd must