Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2020 Google LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * fs-verity integration into incfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Since incfs has its own merkle tree implementation, most of fs-verity code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * is not needed. The key part that is needed is the signature check, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * that is based on the private /proc/sys/fs/verity/require_signatures value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * and a private keyring. Thus the first change is to modify verity code to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * export a version of fsverity_verify_signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * fs-verity integration then consists of the following modifications:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * 1. Add the (optional) verity signature to the incfs file format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * 2. Add a pointer to the digest of the fs-verity descriptor struct to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *    data_file struct that incfs attaches to each file inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * 3. Add the following ioclts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *  - FS_IOC_ENABLE_VERITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *  - FS_IOC_GETFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *  - FS_IOC_MEASURE_VERITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * 4. When FS_IOC_ENABLE_VERITY is called on a non-verity file, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *    fs-verity descriptor struct is populated and digested. If it passes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *    signature check or the signature is NULL and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *    fs.verity.require_signatures=0, then the S_VERITY flag is set and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *    xattr incfs.verity is set. If the signature is non-NULL, an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *    INCFS_MD_VERITY_SIGNATURE is added to the backing file containing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *    signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * 5. When a file with an incfs.verity xattr's inode is initialized, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *    inode’s S_VERITY flag is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * 6. When a file with the S_VERITY flag set on its inode is opened, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *    data_file is checked for its verity digest. If the file doesn’t have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *    digest, the file’s digest is calculated as above, checked, and set, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *    open is denied if it is not valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * 7. FS_IOC_GETFLAGS simply returns the value of the S_VERITY flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * 8. FS_IOC_MEASURE_VERITY simply returns the cached digest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * 9. The final complication is that if FS_IOC_ENABLE_VERITY is called on a file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *    which doesn’t have a merkle tree, the merkle tree is calculated before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *    rest of the process is completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <crypto/sha.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <linux/fsverity.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include "verity.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #include "data_mgmt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #include "format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include "integrity.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #include "vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define FS_VERITY_MAX_SIGNATURE_SIZE	16128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static int incfs_get_root_hash(struct file *filp, u8 *root_hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct data_file *df = get_incfs_data_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (!df)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	memcpy(root_hash, df->df_hash_tree->root_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	       df->df_hash_tree->alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static int incfs_end_enable_verity(struct file *filp, u8 *sig, size_t sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct mem_range signature = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		.data = sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		.len = sig_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct data_file *df = get_incfs_data_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct backing_file_context *bfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct incfs_df_verity_signature *vs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (!df || !df->df_backing_file_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		vs = kzalloc(sizeof(*vs), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		if (!vs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	bfc = df->df_backing_file_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	error = mutex_lock_interruptible(&bfc->bc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	error = incfs_write_verity_signature_to_backing_file(bfc, signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 							     &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	mutex_unlock(&bfc->bc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	 * Set verity xattr so we can set S_VERITY without opening backing file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	error = vfs_setxattr(bfc->bc_file->f_path.dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			     INCFS_XATTR_VERITY_NAME, NULL, 0, XATTR_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		pr_warn("incfs: error setting verity xattr: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		*vs = (struct incfs_df_verity_signature) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			.size = signature.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			.offset = offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		df->df_verity_signature = vs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		vs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	inode_set_flags(inode, S_VERITY, S_VERITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	kfree(vs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int incfs_compute_file_digest(struct incfs_hash_alg *alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				struct fsverity_descriptor *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				u8 *digest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	SHASH_DESC_ON_STACK(d, alg->shash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	d->tfm = alg->shash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return crypto_shash_digest(d, (u8 *)desc, sizeof(*desc), digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static enum incfs_hash_tree_algorithm incfs_convert_fsverity_hash_alg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 								int hash_alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	switch (hash_alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	case FS_VERITY_HASH_ALG_SHA256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return INCFS_HASH_TREE_SHA256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static struct mem_range incfs_get_verity_digest(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct inode_info *node = get_incfs_node(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct data_file *df;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct mem_range verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		pr_warn("Invalid inode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return range(NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	df = node->n_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	 * Pairs with the cmpxchg_release() in incfs_set_verity_digest().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 * I.e., another task may publish ->df_verity_file_digest concurrently,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 * to safely ACQUIRE the memory the other task published.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	verity_file_digest.data = smp_load_acquire(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 					&df->df_verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	verity_file_digest.len = df->df_verity_file_digest.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	return verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void incfs_set_verity_digest(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				     struct mem_range verity_file_digest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct inode_info *node = get_incfs_node(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	struct data_file *df;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		pr_warn("Invalid inode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		kfree(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	df = node->n_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	df->df_verity_file_digest.len = verity_file_digest.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	 * Multiple tasks may race to set ->df_verity_file_digest.data, so use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 * cmpxchg_release().  This pairs with the smp_load_acquire() in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * incfs_get_verity_digest().  I.e., here we publish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 * ->df_verity_file_digest.data, with a RELEASE barrier so that other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 * tasks can ACQUIRE it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (cmpxchg_release(&df->df_verity_file_digest.data, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			    verity_file_digest.data) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		/* Lost the race, so free the file_digest we allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		kfree(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * Calculate the digest of the fsverity_descriptor. The signature (if present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * is also checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static struct mem_range incfs_calc_verity_digest_from_desc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 					const struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 					struct fsverity_descriptor *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 					u8 *signature, size_t sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	enum incfs_hash_tree_algorithm incfs_hash_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct mem_range verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct incfs_hash_alg *hash_alg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	incfs_hash_alg = incfs_convert_fsverity_hash_alg(desc->hash_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (incfs_hash_alg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return range(ERR_PTR(incfs_hash_alg), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	hash_alg = incfs_get_hash_alg(incfs_hash_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (IS_ERR(hash_alg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		return range((u8 *)hash_alg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	verity_file_digest = range(kzalloc(hash_alg->digest_size, GFP_KERNEL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				   hash_alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (!verity_file_digest.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		return range(ERR_PTR(-ENOMEM), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	err = incfs_compute_file_digest(hash_alg, desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 					verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		pr_err("Error %d computing file digest", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	pr_debug("Computed file digest: %s:%*phN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		 hash_alg->name, (int) verity_file_digest.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		 verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	err = __fsverity_verify_signature(inode, signature, sig_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					  verity_file_digest.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 					  desc->hash_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		kfree(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		verity_file_digest = range(ERR_PTR(err), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	return verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static struct fsverity_descriptor *incfs_get_fsverity_descriptor(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 					struct file *filp, int hash_algorithm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	struct fsverity_descriptor *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	*desc = (struct fsverity_descriptor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		.version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		.hash_algorithm = hash_algorithm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		.log_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		.data_size = cpu_to_le64(inode->i_size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	err = incfs_get_root_hash(filp, desc->root_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static struct mem_range incfs_calc_verity_digest(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 					struct inode *inode, struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 					u8 *signature, size_t signature_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 					int hash_algorithm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 							hash_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	struct mem_range verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (IS_ERR(desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return range((u8 *)desc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	verity_file_digest = incfs_calc_verity_digest_from_desc(inode, desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 						signature, signature_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	return verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int incfs_build_merkle_tree(struct file *f, struct data_file *df,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			     struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			     struct mtree *hash_tree, loff_t hash_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			     struct incfs_hash_alg *alg, struct mem_range hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	int limit, lvl, i, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct mem_range buf = {.len = INCFS_DATA_FILE_BLOCK_SIZE};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	struct mem_range tmp = {.len = 2 * INCFS_DATA_FILE_BLOCK_SIZE};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	buf.data = (u8 *)__get_free_pages(GFP_NOFS, get_order(buf.len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	tmp.data = (u8 *)__get_free_pages(GFP_NOFS, get_order(tmp.len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (!buf.data || !tmp.data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	 * lvl - 1 is the level we are reading, lvl the level we are writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	 * lvl == -1 means actual blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	 * lvl == hash_tree->depth means root hash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	limit = df->df_data_block_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	for (lvl = 0; lvl <= hash_tree->depth; lvl++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		for (i = 0; i < limit; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			loff_t hash_level_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			struct mem_range partial_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			if (lvl == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				result = incfs_read_data_file_block(partial_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 						f, i, tmp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				hash_level_offset = hash_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				       hash_tree->hash_level_suboffset[lvl - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				result = incfs_kread(bfc, partial_buf.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 						partial_buf.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 						hash_level_offset + i *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 						INCFS_DATA_FILE_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				error = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			partial_buf.len = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			error = incfs_calc_digest(alg, partial_buf, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			 * last level - only one hash to take and it is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			 * in the incfs signature record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			if (lvl == hash_tree->depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			hash_level_offset = hash_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				hash_tree->hash_level_suboffset[lvl];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			result = incfs_kwrite(bfc, hash.data, hash.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 					hash_level_offset + hash.len * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 				error = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			if (result != hash.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		limit = DIV_ROUND_UP(limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 				     INCFS_DATA_FILE_BLOCK_SIZE / hash.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	free_pages((unsigned long)tmp.data, get_order(tmp.len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	free_pages((unsigned long)buf.data, get_order(buf.len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * incfs files have a signature record that is separate from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * verity_signature record. The signature record does not actually contain a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  * signature, rather it contains the size/offset of the hash tree, and a binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * blob which contains the root hash and potentially a signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * If the file was created with a signature record, then this function simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  * returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  * Otherwise it will create a signature record with a minimal binary blob as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * defined by the structure below, create space for the hash tree and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * populate it using incfs_build_merkle_tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int incfs_add_signature_record(struct file *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	/* See incfs_parse_signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		__le32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		__le32 size_of_hash_info_section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			__le32 hash_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			u8 log2_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			__le32 salt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			u8 salt[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			__le32 hash_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			u8 root_hash[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		} __packed hash_section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		__le32 size_of_signing_info_section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		u8 signing_info_section[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	} __packed sig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		.version = cpu_to_le32(INCFS_SIGNATURE_VERSION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		.size_of_hash_info_section =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			cpu_to_le32(sizeof(sig.hash_section)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		.hash_section = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			.hash_algorithm = cpu_to_le32(INCFS_HASH_TREE_SHA256),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			.log2_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			.hash_size = cpu_to_le32(SHA256_DIGEST_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	struct data_file *df = get_incfs_data_file(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct mtree *hash_tree = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct backing_file_context *bfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	loff_t hash_offset, sig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	struct incfs_hash_alg *alg = incfs_get_hash_alg(INCFS_HASH_TREE_SHA256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	u8 hash_buf[INCFS_MAX_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	int hash_size = alg->digest_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	struct mem_range hash = range(hash_buf, hash_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	struct incfs_df_signature *signature = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if (!df)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (df->df_header_flags & INCFS_FILE_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	/* Already signed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (df->df_signature && df->df_hash_tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (df->df_signature || df->df_hash_tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	/* Add signature metadata record to file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	hash_tree = incfs_alloc_mtree(range((u8 *)&sig, sizeof(sig)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 				      df->df_data_block_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (IS_ERR(hash_tree))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		return PTR_ERR(hash_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	bfc = df->df_backing_file_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	if (!bfc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	error = mutex_lock_interruptible(&bfc->bc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	error = incfs_write_signature_to_backing_file(bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				range((u8 *)&sig, sizeof(sig)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 				hash_tree->hash_tree_area_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				&hash_offset, &sig_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	mutex_unlock(&bfc->bc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* Populate merkle tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	error = incfs_build_merkle_tree(f, df, bfc, hash_tree, hash_offset, alg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				  hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	/* Update signature metadata record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	memcpy(sig.hash_section.root_hash, hash.data, alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	result = incfs_kwrite(bfc, &sig, sizeof(sig), sig_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		error = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	if (result != sizeof(sig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	/* Update in-memory records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	memcpy(hash_tree->root_hash, hash.data, alg->digest_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	signature = kzalloc(sizeof(*signature), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	if (!signature) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	*signature = (struct incfs_df_signature) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		.hash_offset = hash_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		.hash_size = hash_tree->hash_tree_area_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		.sig_offset = sig_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		.sig_size = sizeof(sig),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	df->df_signature = signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	signature = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	 * Use memory barrier to prevent readpage seeing the hash tree until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	 * it's fully there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	smp_store_release(&df->df_hash_tree, hash_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	hash_tree = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	kfree(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	kfree(hash_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int incfs_enable_verity(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			 const struct fsverity_enable_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	struct data_file *df = get_incfs_data_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	u8 *signature = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	struct mem_range verity_file_digest = range(NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	if (!df)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	err = mutex_lock_interruptible(&df->df_enable_verity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	if (IS_VERITY(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	err = incfs_add_signature_record(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	/* Get the signature if the user provided one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (arg->sig_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		signature = memdup_user(u64_to_user_ptr(arg->sig_ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 					arg->sig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		if (IS_ERR(signature)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			err = PTR_ERR(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			signature = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	verity_file_digest = incfs_calc_verity_digest(inode, filp, signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 					arg->sig_size, arg->hash_algorithm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (IS_ERR(verity_file_digest.data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		err = PTR_ERR(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		verity_file_digest.data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	err = incfs_end_enable_verity(filp, signature, arg->sig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	/* Successfully enabled verity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	incfs_set_verity_digest(inode, verity_file_digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	verity_file_digest.data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	mutex_unlock(&df->df_enable_verity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	kfree(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	kfree(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		pr_err("%s failed with err %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int incfs_ioctl_enable_verity(struct file *filp, const void __user *uarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	struct fsverity_enable_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	if (copy_from_user(&arg, uarg, sizeof(arg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	if (arg.version != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	if (arg.__reserved1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	    memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	if (arg.hash_algorithm != FS_VERITY_HASH_ALG_SHA256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if (arg.block_size != PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	if (arg.salt_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		return -EISDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	if (!S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	return incfs_enable_verity(filp, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static u8 *incfs_get_verity_signature(struct file *filp, size_t *sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	struct data_file *df = get_incfs_data_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct incfs_df_verity_signature *vs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	u8 *signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	if (!df || !df->df_backing_file_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		return ERR_PTR(-EFSCORRUPTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	vs = df->df_verity_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (!vs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		*sig_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	if (!vs->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		*sig_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		return ERR_PTR(-EFSCORRUPTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	signature = kzalloc(vs->size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (!signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	res = incfs_kread(df->df_backing_file_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			  signature, vs->size, vs->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if (res != vs->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	*sig_size = vs->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	return signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	kfree(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	return ERR_PTR(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Ensure data_file->df_verity_file_digest is populated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int ensure_verity_info(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	struct mem_range verity_file_digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	u8 *signature = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	size_t sig_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	/* See if this file's verity file digest is already cached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	verity_file_digest = incfs_get_verity_digest(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (verity_file_digest.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	signature = incfs_get_verity_signature(filp, &sig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if (IS_ERR(signature))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		return PTR_ERR(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	verity_file_digest = incfs_calc_verity_digest(inode, filp, signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 						     sig_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 						     FS_VERITY_HASH_ALG_SHA256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	if (IS_ERR(verity_file_digest.data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		err = PTR_ERR(verity_file_digest.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	incfs_set_verity_digest(inode, verity_file_digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	kfree(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)  * incfs_fsverity_file_open() - prepare to open a file that may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)  * verity-enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)  * @inode: the inode being opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)  * @filp: the struct file being set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)  * When opening a verity file, set up data_file->df_verity_file_digest if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)  * already done. Note that incfs does not allow opening for writing, so there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * no need for that check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int incfs_fsverity_file_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	if (IS_VERITY(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		return ensure_verity_info(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int incfs_ioctl_measure_verity(struct file *filp, void __user *_uarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	struct inode *inode = file_inode(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	struct mem_range verity_file_digest = incfs_get_verity_digest(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	struct fsverity_digest __user *uarg = _uarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	struct fsverity_digest arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	if (!verity_file_digest.data || !verity_file_digest.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		return -ENODATA; /* not a verity file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	 * The user specifies the digest_size their buffer has space for; we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	 * return the digest if it fits in the available space.  We write back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	 * the actual size, which may be shorter than the user-specified size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	if (get_user(arg.digest_size, &uarg->digest_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	if (arg.digest_size < verity_file_digest.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	memset(&arg, 0, sizeof(arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	arg.digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	arg.digest_size = verity_file_digest.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	if (copy_to_user(uarg, &arg, sizeof(arg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (copy_to_user(uarg->digest, verity_file_digest.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 			 verity_file_digest.len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int incfs_read_merkle_tree(struct file *filp, void __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 				  u64 start_offset, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	struct mem_range tmp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	size_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	struct data_file *df = get_incfs_data_file(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (!df)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	tmp_buf = (struct mem_range) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		.data = kzalloc(INCFS_DATA_FILE_BLOCK_SIZE, GFP_NOFS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		.len = INCFS_DATA_FILE_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	if (!tmp_buf.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	for (offset = start_offset; offset < start_offset + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	     offset += tmp_buf.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		err = incfs_read_merkle_tree_blocks(tmp_buf, df, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		if (err != tmp_buf.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		if (copy_to_user(buf, tmp_buf.data, tmp_buf.len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		buf += tmp_buf.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		retval += tmp_buf.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	kfree(tmp_buf.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	return retval ? retval : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static int incfs_read_descriptor(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 				 void __user *buf, u64 offset, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 						FS_VERITY_HASH_ALG_SHA256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	if (IS_ERR(desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		return PTR_ERR(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	length = min_t(u64, length, sizeof(*desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	err = copy_to_user(buf, desc, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	return err ? err : length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static int incfs_read_signature(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 				void __user *buf, u64 offset, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	size_t sig_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	static u8 *signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	signature = incfs_get_verity_signature(filp, &sig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	if (IS_ERR(signature))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		return PTR_ERR(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	if (!signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	length = min_t(u64, length, sig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	err = copy_to_user(buf, signature, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	kfree(signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	return err ? err : length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int incfs_ioctl_read_verity_metadata(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 				     const void __user *uarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	struct fsverity_read_metadata_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	void __user *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	if (copy_from_user(&arg, uarg, sizeof(arg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	if (arg.__reserved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	/* offset + length must not overflow. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	if (arg.offset + arg.length < arg.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	/* Ensure that the return value will fit in INT_MAX. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	length = min_t(u64, arg.length, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	buf = u64_to_user_ptr(arg.buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	switch (arg.metadata_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	case FS_VERITY_METADATA_TYPE_MERKLE_TREE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		return incfs_read_merkle_tree(filp, buf, arg.offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	case FS_VERITY_METADATA_TYPE_DESCRIPTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return incfs_read_descriptor(filp, buf, arg.offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	case FS_VERITY_METADATA_TYPE_SIGNATURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 		return incfs_read_signature(filp, buf, arg.offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }