VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   1) // SPDX-License-Identifier: GPL-2.0
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   2) /*
7bf765dd8442d (Eric Biggers 2020-11-13 13:19:15 -0800   3)  * Verification of builtin signatures
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   4)  *
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   5)  * Copyright 2019 Google LLC
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   6)  */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   7) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   8) #include "fsverity_private.h"
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700   9) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  10) #include <linux/cred.h>
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  11) #include <linux/key.h>
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  12) #include <linux/slab.h>
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  13) #include <linux/verification.h>
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  14) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  15) /*
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  16)  * /proc/sys/fs/verity/require_signatures
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  17)  * If 1, all verity files must have a valid builtin signature.
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  18)  */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  19) static int fsverity_require_signatures;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  20) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  21) /*
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  22)  * Keyring that contains the trusted X.509 certificates.
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  23)  *
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  24)  * Only root (kuid=0) can modify this.  Also, root may use
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  25)  * keyctl_restrict_keyring() to prevent any more additions.
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  26)  */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  27) static struct key *fsverity_keyring;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  28) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  29) /**
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  30)  * fsverity_verify_signature() - check a verity file's signature
6377a38bd345b (Eric Biggers 2020-05-11 12:21:17 -0700  31)  * @vi: the file's fsverity_info
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  32)  * @signature: the file's built-in signature
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  33)  * @sig_size: size of signature in bytes, or 0 if no signature
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  34)  *
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  35)  * If the file includes a signature of its fs-verity file digest, verify it
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  36)  * against the certificates in the fs-verity keyring.
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  37)  *
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  38)  * Return: 0 on success (signature valid or not required); -errno on failure
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  39)  */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  40) int fsverity_verify_signature(const struct fsverity_info *vi,
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  41) 			      const u8 *signature, size_t sig_size)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  42) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  43) 	const struct inode *inode = vi->inode;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  44) 	const struct fsverity_hash_alg *hash_alg = vi->tree_params.hash_alg;
9e90f30e78572 (Eric Biggers 2020-11-13 13:19:16 -0800  45) 	struct fsverity_formatted_digest *d;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  46) 	int err;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  47) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  48) 	if (sig_size == 0) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  49) 		if (fsverity_require_signatures) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  50) 			fsverity_err(inode,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  51) 				     "require_signatures=1, rejecting unsigned file!");
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  52) 			return -EPERM;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  53) 		}
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  54) 		return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  55) 	}
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  56) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  57) 	d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  58) 	if (!d)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  59) 		return -ENOMEM;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  60) 	memcpy(d->magic, "FSVerity", 8);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  61) 	d->digest_algorithm = cpu_to_le16(hash_alg - fsverity_hash_algs);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  62) 	d->digest_size = cpu_to_le16(hash_alg->digest_size);
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800  63) 	memcpy(d->digest, vi->file_digest, hash_alg->digest_size);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  64) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  65) 	err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size,
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800  66) 				     signature, sig_size, fsverity_keyring,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  67) 				     VERIFYING_UNSPECIFIED_SIGNATURE,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  68) 				     NULL, NULL);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  69) 	kfree(d);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  70) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  71) 	if (err) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  72) 		if (err == -ENOKEY)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  73) 			fsverity_err(inode,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  74) 				     "File's signing cert isn't in the fs-verity keyring");
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  75) 		else if (err == -EKEYREJECTED)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  76) 			fsverity_err(inode, "Incorrect file signature");
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  77) 		else if (err == -EBADMSG)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  78) 			fsverity_err(inode, "Malformed file signature");
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  79) 		else
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  80) 			fsverity_err(inode, "Error %d verifying file signature",
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  81) 				     err);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  82) 		return err;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  83) 	}
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  84) 
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800  85) 	pr_debug("Valid signature for file digest %s:%*phN\n",
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800  86) 		 hash_alg->name, hash_alg->digest_size, vi->file_digest);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  87) 	return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  88) }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  89) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  90) #ifdef CONFIG_SYSCTL
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  91) static struct ctl_table_header *fsverity_sysctl_header;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  92) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  93) static const struct ctl_path fsverity_sysctl_path[] = {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  94) 	{ .procname = "fs", },
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  95) 	{ .procname = "verity", },
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  96) 	{ }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  97) };
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  98) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700  99) static struct ctl_table fsverity_sysctl_table[] = {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 100) 	{
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 101) 		.procname       = "require_signatures",
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 102) 		.data           = &fsverity_require_signatures,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 103) 		.maxlen         = sizeof(int),
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 104) 		.mode           = 0644,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 105) 		.proc_handler   = proc_dointvec_minmax,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 106) 		.extra1         = SYSCTL_ZERO,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 107) 		.extra2         = SYSCTL_ONE,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 108) 	},
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 109) 	{ }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 110) };
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 111) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 112) static int __init fsverity_sysctl_init(void)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 113) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 114) 	fsverity_sysctl_header = register_sysctl_paths(fsverity_sysctl_path,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 115) 						       fsverity_sysctl_table);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 116) 	if (!fsverity_sysctl_header) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 117) 		pr_err("sysctl registration failed!\n");
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 118) 		return -ENOMEM;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 119) 	}
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 120) 	return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 121) }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 122) #else /* !CONFIG_SYSCTL */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 123) static inline int __init fsverity_sysctl_init(void)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 124) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 125) 	return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 126) }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 127) #endif /* !CONFIG_SYSCTL */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 128) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 129) int __init fsverity_init_signature(void)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 130) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 131) 	struct key *ring;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 132) 	int err;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 133) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 134) 	ring = keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0),
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 135) 			     current_cred(), KEY_POS_SEARCH |
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 136) 				KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE |
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 137) 				KEY_USR_SEARCH | KEY_USR_SETATTR,
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 138) 			     KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 139) 	if (IS_ERR(ring))
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 140) 		return PTR_ERR(ring);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 141) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 142) 	err = fsverity_sysctl_init();
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 143) 	if (err)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 144) 		goto err_put_ring;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 145) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 146) 	fsverity_keyring = ring;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 147) 	return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 148) 
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 149) err_put_ring:
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 150) 	key_put(ring);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 151) 	return err;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 152) }