summaryrefslogtreecommitdiffstats
path: root/fs/verity/open.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-07-22 18:26:23 +0200
committerEric Biggers <ebiggers@google.com>2019-08-13 04:33:50 +0200
commit432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6 (patch)
treecfcf57b2bb1fbdb1e9b5739f020b0311405363c0 /fs/verity/open.c
parentfs-verity: add SHA-512 support (diff)
downloadlinux-432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6.tar.xz
linux-432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6.zip
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/open.c')
-rw-r--r--fs/verity/open.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/verity/open.c b/fs/verity/open.c
index 3636a1ed8e2c..63d1004b688c 100644
--- a/fs/verity/open.c
+++ b/fs/verity/open.c
@@ -122,22 +122,32 @@ out_err:
return err;
}
-/* Compute the file measurement by hashing the fsverity_descriptor. */
+/*
+ * Compute the file measurement by hashing the fsverity_descriptor excluding the
+ * signature and with the sig_size field set to 0.
+ */
static int compute_file_measurement(const struct fsverity_hash_alg *hash_alg,
- const struct fsverity_descriptor *desc,
+ struct fsverity_descriptor *desc,
u8 *measurement)
{
- return fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), measurement);
+ __le32 sig_size = desc->sig_size;
+ int err;
+
+ desc->sig_size = 0;
+ err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), measurement);
+ desc->sig_size = sig_size;
+
+ return err;
}
/*
* Validate the given fsverity_descriptor and create a new fsverity_info from
- * it.
+ * it. The signature (if present) is also checked.
*/
struct fsverity_info *fsverity_create_info(const struct inode *inode,
- const void *_desc, size_t desc_size)
+ void *_desc, size_t desc_size)
{
- const struct fsverity_descriptor *desc = _desc;
+ struct fsverity_descriptor *desc = _desc;
struct fsverity_info *vi;
int err;
@@ -153,8 +163,7 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode,
return ERR_PTR(-EINVAL);
}
- if (desc->sig_size ||
- memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
+ if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
fsverity_err(inode, "Reserved bits set in descriptor");
return ERR_PTR(-EINVAL);
}
@@ -198,6 +207,8 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode,
pr_debug("Computed file measurement: %s:%*phN\n",
vi->tree_params.hash_alg->name,
vi->tree_params.digest_size, vi->measurement);
+
+ err = fsverity_verify_signature(vi, desc, desc_size);
out:
if (err) {
fsverity_free_info(vi);