VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    1) // SPDX-License-Identifier: GPL-2.0
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    2) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    3)  * Filesystem-level keyring for fscrypt
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    4)  *
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    5)  * Copyright 2019 Google LLC
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    6)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    7) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    8) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700    9)  * This file implements management of fscrypt master keys in the
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   10)  * filesystem-level keyring, including the ioctls:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   11)  *
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   12)  * - FS_IOC_ADD_ENCRYPTION_KEY
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   13)  * - FS_IOC_REMOVE_ENCRYPTION_KEY
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700   14)  * - FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700   15)  * - FS_IOC_GET_ENCRYPTION_KEY_STATUS
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   16)  *
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   17)  * See the "User API" section of Documentation/filesystems/fscrypt.rst for more
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   18)  * information about these ioctls.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   19)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   20) 
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   21) #include <crypto/skcipher.h>
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   22) #include <linux/key-type.h>
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700   23) #include <linux/random.h>
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   24) #include <linux/seq_file.h>
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   25) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   26) #include "fscrypt_private.h"
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   27) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   28) static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   29) {
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   30) 	fscrypt_destroy_hkdf(&secret->hkdf);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   31) 	memzero_explicit(secret, sizeof(*secret));
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   32) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   33) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   34) static void move_master_key_secret(struct fscrypt_master_key_secret *dst,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   35) 				   struct fscrypt_master_key_secret *src)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   36) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   37) 	memcpy(dst, src, sizeof(*dst));
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   38) 	memzero_explicit(src, sizeof(*src));
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   39) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   40) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   41) static void free_master_key(struct fscrypt_master_key *mk)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   42) {
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   43) 	size_t i;
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   44) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   45) 	wipe_master_key_secret(&mk->mk_secret);
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   46) 
3ceb6543e9cf6 (Eric Biggers     2020-10-23 17:51:31 -0700   47) 	for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
5fee36095cda4 (Satya Tangirala  2020-07-02 01:56:05 +0000   48) 		fscrypt_destroy_prepared_key(&mk->mk_direct_keys[i]);
5fee36095cda4 (Satya Tangirala  2020-07-02 01:56:05 +0000   49) 		fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_64_keys[i]);
5fee36095cda4 (Satya Tangirala  2020-07-02 01:56:05 +0000   50) 		fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_32_keys[i]);
b103fb7653fff (Eric Biggers     2019-10-24 14:54:36 -0700   51) 	}
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700   52) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700   53) 	key_put(mk->mk_users);
453431a54934d (Waiman Long      2020-08-06 23:18:13 -0700   54) 	kfree_sensitive(mk);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   55) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   56) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   57) static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   58) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   59) 	if (spec->__reserved)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   60) 		return false;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   61) 	return master_key_spec_len(spec) != 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   62) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   63) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   64) static int fscrypt_key_instantiate(struct key *key,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   65) 				   struct key_preparsed_payload *prep)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   66) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   67) 	key->payload.data[0] = (struct fscrypt_master_key *)prep->data;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   68) 	return 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   69) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   70) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   71) static void fscrypt_key_destroy(struct key *key)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   72) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   73) 	free_master_key(key->payload.data[0]);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   74) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   75) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   76) static void fscrypt_key_describe(const struct key *key, struct seq_file *m)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   77) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   78) 	seq_puts(m, key->description);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   79) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   80) 	if (key_is_positive(key)) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   81) 		const struct fscrypt_master_key *mk = key->payload.data[0];
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   82) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   83) 		if (!is_master_key_secret_present(&mk->mk_secret))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   84) 			seq_puts(m, ": secret removed");
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700   85) 	}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   86) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   87) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   88) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   89)  * Type of key in ->s_master_keys.  Each key of this type represents a master
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   90)  * key which has been added to the filesystem.  Its payload is a
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   91)  * 'struct fscrypt_master_key'.  The "." prefix in the key type name prevents
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   92)  * users from adding keys of this type via the keyrings syscalls rather than via
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   93)  * the intended method of FS_IOC_ADD_ENCRYPTION_KEY.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   94)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   95) static struct key_type key_type_fscrypt = {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   96) 	.name			= "._fscrypt",
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   97) 	.instantiate		= fscrypt_key_instantiate,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   98) 	.destroy		= fscrypt_key_destroy,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700   99) 	.describe		= fscrypt_key_describe,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  100) };
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  101) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  102) static int fscrypt_user_key_instantiate(struct key *key,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  103) 					struct key_preparsed_payload *prep)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  104) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  105) 	/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  106) 	 * We just charge FSCRYPT_MAX_KEY_SIZE bytes to the user's key quota for
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  107) 	 * each key, regardless of the exact key size.  The amount of memory
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  108) 	 * actually used is greater than the size of the raw key anyway.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  109) 	 */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  110) 	return key_payload_reserve(key, FSCRYPT_MAX_KEY_SIZE);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  111) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  112) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  113) static void fscrypt_user_key_describe(const struct key *key, struct seq_file *m)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  114) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  115) 	seq_puts(m, key->description);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  116) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  117) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  118) /*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  119)  * Type of key in ->mk_users.  Each key of this type represents a particular
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  120)  * user who has added a particular master key.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  121)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  122)  * Note that the name of this key type really should be something like
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  123)  * ".fscrypt-user" instead of simply ".fscrypt".  But the shorter name is chosen
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  124)  * mainly for simplicity of presentation in /proc/keys when read by a non-root
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  125)  * user.  And it is expected to be rare that a key is actually added by multiple
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  126)  * users, since users should keep their encryption keys confidential.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  127)  */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  128) static struct key_type key_type_fscrypt_user = {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  129) 	.name			= ".fscrypt",
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  130) 	.instantiate		= fscrypt_user_key_instantiate,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  131) 	.describe		= fscrypt_user_key_describe,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  132) };
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  133) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  134) /* Search ->s_master_keys or ->mk_users */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  135) static struct key *search_fscrypt_keyring(struct key *keyring,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  136) 					  struct key_type *type,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  137) 					  const char *description)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  138) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  139) 	/*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  140) 	 * We need to mark the keyring reference as "possessed" so that we
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  141) 	 * acquire permission to search it, via the KEY_POS_SEARCH permission.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  142) 	 */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  143) 	key_ref_t keyref = make_key_ref(keyring, true /* possessed */);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  144) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  145) 	keyref = keyring_search(keyref, type, description, false);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  146) 	if (IS_ERR(keyref)) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  147) 		if (PTR_ERR(keyref) == -EAGAIN || /* not found */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  148) 		    PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  149) 			keyref = ERR_PTR(-ENOKEY);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  150) 		return ERR_CAST(keyref);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  151) 	}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  152) 	return key_ref_to_ptr(keyref);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  153) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  154) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  155) #define FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE	\
c593642c8be04 (Pankaj Bharadiya 2019-12-09 10:31:43 -0800  156) 	(CONST_STRLEN("fscrypt-") + sizeof_field(struct super_block, s_id))
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  157) 
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700  158) #define FSCRYPT_MK_DESCRIPTION_SIZE	(2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  159) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  160) #define FSCRYPT_MK_USERS_DESCRIPTION_SIZE	\
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  161) 	(CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  162) 	 CONST_STRLEN("-users") + 1)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  163) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  164) #define FSCRYPT_MK_USER_DESCRIPTION_SIZE	\
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  165) 	(2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  166) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  167) static void format_fs_keyring_description(
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  168) 			char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE],
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  169) 			const struct super_block *sb)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  170) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  171) 	sprintf(description, "fscrypt-%s", sb->s_id);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  172) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  173) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  174) static void format_mk_description(
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  175) 			char description[FSCRYPT_MK_DESCRIPTION_SIZE],
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  176) 			const struct fscrypt_key_specifier *mk_spec)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  177) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  178) 	sprintf(description, "%*phN",
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  179) 		master_key_spec_len(mk_spec), (u8 *)&mk_spec->u);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  180) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  181) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  182) static void format_mk_users_keyring_description(
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  183) 			char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE],
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  184) 			const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  185) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  186) 	sprintf(description, "fscrypt-%*phN-users",
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  187) 		FSCRYPT_KEY_IDENTIFIER_SIZE, mk_identifier);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  188) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  189) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  190) static void format_mk_user_description(
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  191) 			char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE],
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  192) 			const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  193) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  194) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  195) 	sprintf(description, "%*phN.uid.%u", FSCRYPT_KEY_IDENTIFIER_SIZE,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  196) 		mk_identifier, __kuid_val(current_fsuid()));
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  197) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  198) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  199) /* Create ->s_master_keys if needed.  Synchronized by fscrypt_add_key_mutex. */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  200) static int allocate_filesystem_keyring(struct super_block *sb)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  201) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  202) 	char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE];
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  203) 	struct key *keyring;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  204) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  205) 	if (sb->s_master_keys)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  206) 		return 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  207) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  208) 	format_fs_keyring_description(description, sb);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  209) 	keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  210) 				current_cred(), KEY_POS_SEARCH |
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  211) 				  KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  212) 				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  213) 	if (IS_ERR(keyring))
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  214) 		return PTR_ERR(keyring);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  215) 
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  216) 	/*
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  217) 	 * Pairs with the smp_load_acquire() in fscrypt_find_master_key().
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  218) 	 * I.e., here we publish ->s_master_keys with a RELEASE barrier so that
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  219) 	 * concurrent tasks can ACQUIRE it.
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  220) 	 */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  221) 	smp_store_release(&sb->s_master_keys, keyring);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  222) 	return 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  223) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  224) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  225) void fscrypt_sb_free(struct super_block *sb)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  226) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  227) 	key_put(sb->s_master_keys);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  228) 	sb->s_master_keys = NULL;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  229) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  230) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  231) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  232)  * Find the specified master key in ->s_master_keys.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  233)  * Returns ERR_PTR(-ENOKEY) if not found.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  234)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  235) struct key *fscrypt_find_master_key(struct super_block *sb,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  236) 				    const struct fscrypt_key_specifier *mk_spec)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  237) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  238) 	struct key *keyring;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  239) 	char description[FSCRYPT_MK_DESCRIPTION_SIZE];
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  240) 
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  241) 	/*
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  242) 	 * Pairs with the smp_store_release() in allocate_filesystem_keyring().
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  243) 	 * I.e., another task can publish ->s_master_keys concurrently,
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  244) 	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  245) 	 * to safely ACQUIRE the memory the other task published.
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  246) 	 */
777afe4e68d7a (Eric Biggers     2020-07-21 15:59:18 -0700  247) 	keyring = smp_load_acquire(&sb->s_master_keys);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  248) 	if (keyring == NULL)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  249) 		return ERR_PTR(-ENOKEY); /* No keyring yet, so no keys yet. */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  250) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  251) 	format_mk_description(description, mk_spec);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  252) 	return search_fscrypt_keyring(keyring, &key_type_fscrypt, description);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  253) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  254) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  255) static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  256) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  257) 	char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE];
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  258) 	struct key *keyring;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  259) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  260) 	format_mk_users_keyring_description(description,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  261) 					    mk->mk_spec.u.identifier);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  262) 	keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  263) 				current_cred(), KEY_POS_SEARCH |
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  264) 				  KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  265) 				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  266) 	if (IS_ERR(keyring))
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  267) 		return PTR_ERR(keyring);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  268) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  269) 	mk->mk_users = keyring;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  270) 	return 0;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  271) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  272) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  273) /*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  274)  * Find the current user's "key" in the master key's ->mk_users.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  275)  * Returns ERR_PTR(-ENOKEY) if not found.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  276)  */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  277) static struct key *find_master_key_user(struct fscrypt_master_key *mk)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  278) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  279) 	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  280) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  281) 	format_mk_user_description(description, mk->mk_spec.u.identifier);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  282) 	return search_fscrypt_keyring(mk->mk_users, &key_type_fscrypt_user,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  283) 				      description);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  284) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  285) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  286) /*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  287)  * Give the current user a "key" in ->mk_users.  This charges the user's quota
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  288)  * and marks the master key as added by the current user, so that it cannot be
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  289)  * removed by another user with the key.  Either the master key's key->sem must
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  290)  * be held for write, or the master key must be still undergoing initialization.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  291)  */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  292) static int add_master_key_user(struct fscrypt_master_key *mk)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  293) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  294) 	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  295) 	struct key *mk_user;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  296) 	int err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  297) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  298) 	format_mk_user_description(description, mk->mk_spec.u.identifier);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  299) 	mk_user = key_alloc(&key_type_fscrypt_user, description,
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  300) 			    current_fsuid(), current_gid(), current_cred(),
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  301) 			    KEY_POS_SEARCH | KEY_USR_VIEW, 0, NULL);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  302) 	if (IS_ERR(mk_user))
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  303) 		return PTR_ERR(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  304) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  305) 	err = key_instantiate_and_link(mk_user, NULL, 0, mk->mk_users, NULL);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  306) 	key_put(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  307) 	return err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  308) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  309) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  310) /*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  311)  * Remove the current user's "key" from ->mk_users.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  312)  * The master key's key->sem must be held for write.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  313)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  314)  * Returns 0 if removed, -ENOKEY if not found, or another -errno code.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  315)  */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  316) static int remove_master_key_user(struct fscrypt_master_key *mk)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  317) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  318) 	struct key *mk_user;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  319) 	int err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  320) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  321) 	mk_user = find_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  322) 	if (IS_ERR(mk_user))
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  323) 		return PTR_ERR(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  324) 	err = key_unlink(mk->mk_users, mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  325) 	key_put(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  326) 	return err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  327) }
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  328) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  329) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  330)  * Allocate a new fscrypt_master_key which contains the given secret, set it as
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  331)  * the payload of a new 'struct key' of type fscrypt, and link the 'struct key'
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  332)  * into the given keyring.  Synchronized by fscrypt_add_key_mutex.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  333)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  334) static int add_new_master_key(struct fscrypt_master_key_secret *secret,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  335) 			      const struct fscrypt_key_specifier *mk_spec,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  336) 			      struct key *keyring)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  337) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  338) 	struct fscrypt_master_key *mk;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  339) 	char description[FSCRYPT_MK_DESCRIPTION_SIZE];
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  340) 	struct key *key;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  341) 	int err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  342) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  343) 	mk = kzalloc(sizeof(*mk), GFP_KERNEL);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  344) 	if (!mk)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  345) 		return -ENOMEM;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  346) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  347) 	mk->mk_spec = *mk_spec;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  348) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  349) 	move_master_key_secret(&mk->mk_secret, secret);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  350) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  351) 	refcount_set(&mk->mk_refcount, 1); /* secret is present */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  352) 	INIT_LIST_HEAD(&mk->mk_decrypted_inodes);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  353) 	spin_lock_init(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  354) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  355) 	if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  356) 		err = allocate_master_key_users_keyring(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  357) 		if (err)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  358) 			goto out_free_mk;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  359) 		err = add_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  360) 		if (err)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  361) 			goto out_free_mk;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  362) 	}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  363) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  364) 	/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  365) 	 * Note that we don't charge this key to anyone's quota, since when
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  366) 	 * ->mk_users is in use those keys are charged instead, and otherwise
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  367) 	 * (when ->mk_users isn't in use) only root can add these keys.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  368) 	 */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  369) 	format_mk_description(description, mk_spec);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  370) 	key = key_alloc(&key_type_fscrypt, description,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  371) 			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  372) 			KEY_POS_SEARCH | KEY_USR_SEARCH | KEY_USR_VIEW,
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  373) 			KEY_ALLOC_NOT_IN_QUOTA, NULL);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  374) 	if (IS_ERR(key)) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  375) 		err = PTR_ERR(key);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  376) 		goto out_free_mk;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  377) 	}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  378) 	err = key_instantiate_and_link(key, mk, sizeof(*mk), keyring, NULL);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  379) 	key_put(key);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  380) 	if (err)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  381) 		goto out_free_mk;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  382) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  383) 	return 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  384) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  385) out_free_mk:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  386) 	free_master_key(mk);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  387) 	return err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  388) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  389) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  390) #define KEY_DEAD	1
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  391) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  392) static int add_existing_master_key(struct fscrypt_master_key *mk,
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  393) 				   struct fscrypt_master_key_secret *secret)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  394) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  395) 	struct key *mk_user;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  396) 	bool rekey;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  397) 	int err;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  398) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  399) 	/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  400) 	 * If the current user is already in ->mk_users, then there's nothing to
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  401) 	 * do.  (Not applicable for v1 policy keys, which have NULL ->mk_users.)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  402) 	 */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  403) 	if (mk->mk_users) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  404) 		mk_user = find_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  405) 		if (mk_user != ERR_PTR(-ENOKEY)) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  406) 			if (IS_ERR(mk_user))
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  407) 				return PTR_ERR(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  408) 			key_put(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  409) 			return 0;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  410) 		}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  411) 	}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  412) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  413) 	/* If we'll be re-adding ->mk_secret, try to take the reference. */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  414) 	rekey = !is_master_key_secret_present(&mk->mk_secret);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  415) 	if (rekey && !refcount_inc_not_zero(&mk->mk_refcount))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  416) 		return KEY_DEAD;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  417) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  418) 	/* Add the current user to ->mk_users, if applicable. */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  419) 	if (mk->mk_users) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  420) 		err = add_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  421) 		if (err) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  422) 			if (rekey && refcount_dec_and_test(&mk->mk_refcount))
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  423) 				return KEY_DEAD;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  424) 			return err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  425) 		}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  426) 	}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  427) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  428) 	/* Re-add the secret if needed. */
4a4b8721f1a5e (Eric Biggers     2020-11-16 19:26:26 -0800  429) 	if (rekey)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  430) 		move_master_key_secret(&mk->mk_secret, secret);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  431) 	return 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  432) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  433) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  434) static int do_add_master_key(struct super_block *sb,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  435) 			     struct fscrypt_master_key_secret *secret,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  436) 			     const struct fscrypt_key_specifier *mk_spec)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  437) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  438) 	static DEFINE_MUTEX(fscrypt_add_key_mutex);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  439) 	struct key *key;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  440) 	int err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  441) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  442) 	mutex_lock(&fscrypt_add_key_mutex); /* serialize find + link */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  443) retry:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  444) 	key = fscrypt_find_master_key(sb, mk_spec);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  445) 	if (IS_ERR(key)) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  446) 		err = PTR_ERR(key);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  447) 		if (err != -ENOKEY)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  448) 			goto out_unlock;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  449) 		/* Didn't find the key in ->s_master_keys.  Add it. */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  450) 		err = allocate_filesystem_keyring(sb);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  451) 		if (err)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  452) 			goto out_unlock;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  453) 		err = add_new_master_key(secret, mk_spec, sb->s_master_keys);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  454) 	} else {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  455) 		/*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  456) 		 * Found the key in ->s_master_keys.  Re-add the secret if
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  457) 		 * needed, and add the user to ->mk_users if needed.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  458) 		 */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  459) 		down_write(&key->sem);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  460) 		err = add_existing_master_key(key->payload.data[0], secret);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  461) 		up_write(&key->sem);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  462) 		if (err == KEY_DEAD) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  463) 			/* Key being removed or needs to be removed */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  464) 			key_invalidate(key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  465) 			key_put(key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  466) 			goto retry;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  467) 		}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  468) 		key_put(key);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  469) 	}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  470) out_unlock:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  471) 	mutex_unlock(&fscrypt_add_key_mutex);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  472) 	return err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  473) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  474) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  475) static int add_master_key(struct super_block *sb,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  476) 			  struct fscrypt_master_key_secret *secret,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  477) 			  struct fscrypt_key_specifier *key_spec)
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  478) {
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  479) 	int err;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  480) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  481) 	if (key_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  482) 		err = fscrypt_init_hkdf(&secret->hkdf, secret->raw,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  483) 					secret->size);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  484) 		if (err)
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  485) 			return err;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  486) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  487) 		/*
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  488) 		 * Now that the HKDF context is initialized, the raw key is no
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  489) 		 * longer needed.
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  490) 		 */
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  491) 		memzero_explicit(secret->raw, secret->size);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  492) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  493) 		/* Calculate the key identifier */
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  494) 		err = fscrypt_hkdf_expand(&secret->hkdf,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  495) 					  HKDF_CONTEXT_KEY_IDENTIFIER, NULL, 0,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  496) 					  key_spec->u.identifier,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  497) 					  FSCRYPT_KEY_IDENTIFIER_SIZE);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  498) 		if (err)
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  499) 			return err;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  500) 	}
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  501) 	return do_add_master_key(sb, secret, key_spec);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  502) }
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  503) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  504) static int fscrypt_provisioning_key_preparse(struct key_preparsed_payload *prep)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  505) {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  506) 	const struct fscrypt_provisioning_key_payload *payload = prep->data;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  507) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  508) 	if (prep->datalen < sizeof(*payload) + FSCRYPT_MIN_KEY_SIZE ||
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  509) 	    prep->datalen > sizeof(*payload) + FSCRYPT_MAX_KEY_SIZE)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  510) 		return -EINVAL;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  511) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  512) 	if (payload->type != FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  513) 	    payload->type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  514) 		return -EINVAL;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  515) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  516) 	if (payload->__reserved)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  517) 		return -EINVAL;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  518) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  519) 	prep->payload.data[0] = kmemdup(payload, prep->datalen, GFP_KERNEL);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  520) 	if (!prep->payload.data[0])
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  521) 		return -ENOMEM;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  522) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  523) 	prep->quotalen = prep->datalen;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  524) 	return 0;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  525) }
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  526) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  527) static void fscrypt_provisioning_key_free_preparse(
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  528) 					struct key_preparsed_payload *prep)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  529) {
453431a54934d (Waiman Long      2020-08-06 23:18:13 -0700  530) 	kfree_sensitive(prep->payload.data[0]);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  531) }
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  532) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  533) static void fscrypt_provisioning_key_describe(const struct key *key,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  534) 					      struct seq_file *m)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  535) {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  536) 	seq_puts(m, key->description);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  537) 	if (key_is_positive(key)) {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  538) 		const struct fscrypt_provisioning_key_payload *payload =
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  539) 			key->payload.data[0];
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  540) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  541) 		seq_printf(m, ": %u [%u]", key->datalen, payload->type);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  542) 	}
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  543) }
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  544) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  545) static void fscrypt_provisioning_key_destroy(struct key *key)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  546) {
453431a54934d (Waiman Long      2020-08-06 23:18:13 -0700  547) 	kfree_sensitive(key->payload.data[0]);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  548) }
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  549) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  550) static struct key_type key_type_fscrypt_provisioning = {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  551) 	.name			= "fscrypt-provisioning",
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  552) 	.preparse		= fscrypt_provisioning_key_preparse,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  553) 	.free_preparse		= fscrypt_provisioning_key_free_preparse,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  554) 	.instantiate		= generic_key_instantiate,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  555) 	.describe		= fscrypt_provisioning_key_describe,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  556) 	.destroy		= fscrypt_provisioning_key_destroy,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  557) };
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  558) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  559) /*
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  560)  * Retrieve the raw key from the Linux keyring key specified by 'key_id', and
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  561)  * store it into 'secret'.
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  562)  *
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  563)  * The key must be of type "fscrypt-provisioning" and must have the field
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  564)  * fscrypt_provisioning_key_payload::type set to 'type', indicating that it's
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  565)  * only usable with fscrypt with the particular KDF version identified by
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  566)  * 'type'.  We don't use the "logon" key type because there's no way to
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  567)  * completely restrict the use of such keys; they can be used by any kernel API
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  568)  * that accepts "logon" keys and doesn't require a specific service prefix.
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  569)  *
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  570)  * The ability to specify the key via Linux keyring key is intended for cases
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  571)  * where userspace needs to re-add keys after the filesystem is unmounted and
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  572)  * re-mounted.  Most users should just provide the raw key directly instead.
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  573)  */
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  574) static int get_keyring_key(u32 key_id, u32 type,
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  575) 			   struct fscrypt_master_key_secret *secret)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  576) {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  577) 	key_ref_t ref;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  578) 	struct key *key;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  579) 	const struct fscrypt_provisioning_key_payload *payload;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  580) 	int err;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  581) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  582) 	ref = lookup_user_key(key_id, 0, KEY_NEED_SEARCH);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  583) 	if (IS_ERR(ref))
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  584) 		return PTR_ERR(ref);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  585) 	key = key_ref_to_ptr(ref);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  586) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  587) 	if (key->type != &key_type_fscrypt_provisioning)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  588) 		goto bad_key;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  589) 	payload = key->payload.data[0];
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  590) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  591) 	/* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  592) 	if (payload->type != type)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  593) 		goto bad_key;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  594) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  595) 	secret->size = key->datalen - sizeof(*payload);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  596) 	memcpy(secret->raw, payload->raw, secret->size);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  597) 	err = 0;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  598) 	goto out_put;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  599) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  600) bad_key:
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  601) 	err = -EKEYREJECTED;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  602) out_put:
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  603) 	key_ref_put(ref);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  604) 	return err;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  605) }
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  606) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  607) /*
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  608)  * Add a master encryption key to the filesystem, causing all files which were
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  609)  * encrypted with it to appear "unlocked" (decrypted) when accessed.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  610)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  611)  * When adding a key for use by v1 encryption policies, this ioctl is
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  612)  * privileged, and userspace must provide the 'key_descriptor'.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  613)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  614)  * When adding a key for use by v2+ encryption policies, this ioctl is
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  615)  * unprivileged.  This is needed, in general, to allow non-root users to use
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  616)  * encryption without encountering the visibility problems of process-subscribed
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  617)  * keyrings and the inability to properly remove keys.  This works by having
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  618)  * each key identified by its cryptographically secure hash --- the
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  619)  * 'key_identifier'.  The cryptographic hash ensures that a malicious user
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  620)  * cannot add the wrong key for a given identifier.  Furthermore, each added key
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  621)  * is charged to the appropriate user's quota for the keyrings service, which
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  622)  * prevents a malicious user from adding too many keys.  Finally, we forbid a
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  623)  * user from removing a key while other users have added it too, which prevents
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  624)  * a user who knows another user's key from causing a denial-of-service by
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  625)  * removing it at an inopportune time.  (We tolerate that a user who knows a key
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  626)  * can prevent other users from removing it.)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  627)  *
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  628)  * For more details, see the "FS_IOC_ADD_ENCRYPTION_KEY" section of
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  629)  * Documentation/filesystems/fscrypt.rst.
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  630)  */
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  631) int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  632) {
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  633) 	struct super_block *sb = file_inode(filp)->i_sb;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  634) 	struct fscrypt_add_key_arg __user *uarg = _uarg;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  635) 	struct fscrypt_add_key_arg arg;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  636) 	struct fscrypt_master_key_secret secret;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  637) 	int err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  638) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  639) 	if (copy_from_user(&arg, uarg, sizeof(arg)))
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  640) 		return -EFAULT;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  641) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  642) 	if (!valid_key_spec(&arg.key_spec))
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  643) 		return -EINVAL;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  644) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  645) 	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  646) 		return -EINVAL;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  647) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  648) 	/*
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  649) 	 * Only root can add keys that are identified by an arbitrary descriptor
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  650) 	 * rather than by a cryptographic hash --- since otherwise a malicious
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  651) 	 * user could add the wrong key.
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  652) 	 */
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  653) 	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  654) 	    !capable(CAP_SYS_ADMIN))
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  655) 		return -EACCES;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  656) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  657) 	memset(&secret, 0, sizeof(secret));
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  658) 	if (arg.key_id) {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  659) 		if (arg.raw_size != 0)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  660) 			return -EINVAL;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  661) 		err = get_keyring_key(arg.key_id, arg.key_spec.type, &secret);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  662) 		if (err)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  663) 			goto out_wipe_secret;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  664) 	} else {
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  665) 		if (arg.raw_size < FSCRYPT_MIN_KEY_SIZE ||
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  666) 		    arg.raw_size > FSCRYPT_MAX_KEY_SIZE)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  667) 			return -EINVAL;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  668) 		secret.size = arg.raw_size;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  669) 		err = -EFAULT;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  670) 		if (copy_from_user(secret.raw, uarg->raw, secret.size))
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  671) 			goto out_wipe_secret;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800  672) 	}
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  673) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  674) 	err = add_master_key(sb, &secret, &arg.key_spec);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  675) 	if (err)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  676) 		goto out_wipe_secret;
5dae460c2292d (Eric Biggers     2019-08-04 19:35:47 -0700  677) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  678) 	/* Return the key identifier to userspace, if applicable */
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  679) 	err = -EFAULT;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  680) 	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER &&
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  681) 	    copy_to_user(uarg->key_spec.u.identifier, arg.key_spec.u.identifier,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  682) 			 FSCRYPT_KEY_IDENTIFIER_SIZE))
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  683) 		goto out_wipe_secret;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  684) 	err = 0;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  685) out_wipe_secret:
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  686) 	wipe_master_key_secret(&secret);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  687) 	return err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  688) }
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  689) EXPORT_SYMBOL_GPL(fscrypt_ioctl_add_key);
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700  690) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  691) /*
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  692)  * Add the key for '-o test_dummy_encryption' to the filesystem keyring.
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  693)  *
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  694)  * Use a per-boot random key to prevent people from misusing this option.
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  695)  */
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  696) int fscrypt_add_test_dummy_key(struct super_block *sb,
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  697) 			       struct fscrypt_key_specifier *key_spec)
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  698) {
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  699) 	static u8 test_key[FSCRYPT_MAX_KEY_SIZE];
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  700) 	struct fscrypt_master_key_secret secret;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  701) 	int err;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  702) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  703) 	get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  704) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  705) 	memset(&secret, 0, sizeof(secret));
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  706) 	secret.size = FSCRYPT_MAX_KEY_SIZE;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  707) 	memcpy(secret.raw, test_key, FSCRYPT_MAX_KEY_SIZE);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  708) 
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  709) 	err = add_master_key(sb, &secret, key_spec);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  710) 	wipe_master_key_secret(&secret);
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  711) 	return err;
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  712) }
cdeb21da1783a (Eric Biggers     2020-05-12 16:32:49 -0700  713) 
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  714) /*
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  715)  * Verify that the current user has added a master key with the given identifier
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  716)  * (returns -ENOKEY if not).  This is needed to prevent a user from encrypting
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  717)  * their files using some other user's key which they don't actually know.
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  718)  * Cryptographically this isn't much of a problem, but the semantics of this
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  719)  * would be a bit weird, so it's best to just forbid it.
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  720)  *
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  721)  * The system administrator (CAP_FOWNER) can override this, which should be
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  722)  * enough for any use cases where encryption policies are being set using keys
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  723)  * that were chosen ahead of time but aren't available at the moment.
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  724)  *
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  725)  * Note that the key may have already removed by the time this returns, but
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  726)  * that's okay; we just care whether the key was there at some point.
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  727)  *
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  728)  * Return: 0 if the key is added, -ENOKEY if it isn't, or another -errno code
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  729)  */
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  730) int fscrypt_verify_key_added(struct super_block *sb,
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  731) 			     const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  732) {
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  733) 	struct fscrypt_key_specifier mk_spec;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  734) 	struct key *key, *mk_user;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  735) 	struct fscrypt_master_key *mk;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  736) 	int err;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  737) 
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  738) 	mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  739) 	memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  740) 
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  741) 	key = fscrypt_find_master_key(sb, &mk_spec);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  742) 	if (IS_ERR(key)) {
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  743) 		err = PTR_ERR(key);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  744) 		goto out;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  745) 	}
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  746) 	mk = key->payload.data[0];
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  747) 	mk_user = find_master_key_user(mk);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  748) 	if (IS_ERR(mk_user)) {
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  749) 		err = PTR_ERR(mk_user);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  750) 	} else {
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  751) 		key_put(mk_user);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  752) 		err = 0;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  753) 	}
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  754) 	key_put(key);
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  755) out:
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  756) 	if (err == -ENOKEY && capable(CAP_FOWNER))
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  757) 		err = 0;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  758) 	return err;
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  759) }
5ab7189a31bad (Eric Biggers     2019-08-04 19:35:48 -0700  760) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  761) /*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  762)  * Try to evict the inode's dentries from the dentry cache.  If the inode is a
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  763)  * directory, then it can have at most one dentry; however, that dentry may be
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  764)  * pinned by child dentries, so first try to evict the children too.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  765)  */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  766) static void shrink_dcache_inode(struct inode *inode)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  767) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  768) 	struct dentry *dentry;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  769) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  770) 	if (S_ISDIR(inode->i_mode)) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  771) 		dentry = d_find_any_alias(inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  772) 		if (dentry) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  773) 			shrink_dcache_parent(dentry);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  774) 			dput(dentry);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  775) 		}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  776) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  777) 	d_prune_aliases(inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  778) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  779) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  780) static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  781) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  782) 	struct fscrypt_info *ci;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  783) 	struct inode *inode;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  784) 	struct inode *toput_inode = NULL;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  785) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  786) 	spin_lock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  787) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  788) 	list_for_each_entry(ci, &mk->mk_decrypted_inodes, ci_master_key_link) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  789) 		inode = ci->ci_inode;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  790) 		spin_lock(&inode->i_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  791) 		if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  792) 			spin_unlock(&inode->i_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  793) 			continue;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  794) 		}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  795) 		__iget(inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  796) 		spin_unlock(&inode->i_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  797) 		spin_unlock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  798) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  799) 		shrink_dcache_inode(inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  800) 		iput(toput_inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  801) 		toput_inode = inode;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  802) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  803) 		spin_lock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  804) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  805) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  806) 	spin_unlock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  807) 	iput(toput_inode);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  808) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  809) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  810) static int check_for_busy_inodes(struct super_block *sb,
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  811) 				 struct fscrypt_master_key *mk)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  812) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  813) 	struct list_head *pos;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  814) 	size_t busy_count = 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  815) 	unsigned long ino;
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  816) 	char ino_str[50] = "";
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  817) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  818) 	spin_lock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  819) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  820) 	list_for_each(pos, &mk->mk_decrypted_inodes)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  821) 		busy_count++;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  822) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  823) 	if (busy_count == 0) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  824) 		spin_unlock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  825) 		return 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  826) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  827) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  828) 	{
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  829) 		/* select an example file to show for debugging purposes */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  830) 		struct inode *inode =
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  831) 			list_first_entry(&mk->mk_decrypted_inodes,
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  832) 					 struct fscrypt_info,
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  833) 					 ci_master_key_link)->ci_inode;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  834) 		ino = inode->i_ino;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  835) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  836) 	spin_unlock(&mk->mk_decrypted_inodes_lock);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  837) 
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  838) 	/* If the inode is currently being created, ino may still be 0. */
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  839) 	if (ino)
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  840) 		snprintf(ino_str, sizeof(ino_str), ", including ino %lu", ino);
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  841) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  842) 	fscrypt_warn(NULL,
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  843) 		     "%s: %zu inode(s) still busy after removing key with %s %*phN%s",
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  844) 		     sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec),
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  845) 		     master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u,
ae9ff8ad81b13 (Eric Biggers     2020-09-16 21:11:29 -0700  846) 		     ino_str);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  847) 	return -EBUSY;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  848) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  849) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  850) static int try_to_lock_encrypted_files(struct super_block *sb,
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  851) 				       struct fscrypt_master_key *mk)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  852) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  853) 	int err1;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  854) 	int err2;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  855) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  856) 	/*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  857) 	 * An inode can't be evicted while it is dirty or has dirty pages.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  858) 	 * Thus, we first have to clean the inodes in ->mk_decrypted_inodes.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  859) 	 *
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  860) 	 * Just do it the easy way: call sync_filesystem().  It's overkill, but
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  861) 	 * it works, and it's more important to minimize the amount of caches we
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  862) 	 * drop than the amount of data we sync.  Also, unprivileged users can
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  863) 	 * already call sync_filesystem() via sys_syncfs() or sys_sync().
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  864) 	 */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  865) 	down_read(&sb->s_umount);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  866) 	err1 = sync_filesystem(sb);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  867) 	up_read(&sb->s_umount);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  868) 	/* If a sync error occurs, still try to evict as much as possible. */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  869) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  870) 	/*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  871) 	 * Inodes are pinned by their dentries, so we have to evict their
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  872) 	 * dentries.  shrink_dcache_sb() would suffice, but would be overkill
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  873) 	 * and inappropriate for use by unprivileged users.  So instead go
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  874) 	 * through the inodes' alias lists and try to evict each dentry.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  875) 	 */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  876) 	evict_dentries_for_decrypted_inodes(mk);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  877) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  878) 	/*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  879) 	 * evict_dentries_for_decrypted_inodes() already iput() each inode in
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  880) 	 * the list; any inodes for which that dropped the last reference will
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  881) 	 * have been evicted due to fscrypt_drop_inode() detecting the key
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  882) 	 * removal and telling the VFS to evict the inode.  So to finish, we
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  883) 	 * just need to check whether any inodes couldn't be evicted.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  884) 	 */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  885) 	err2 = check_for_busy_inodes(sb, mk);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  886) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  887) 	return err1 ?: err2;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  888) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  889) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  890) /*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  891)  * Try to remove an fscrypt master encryption key.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  892)  *
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  893)  * FS_IOC_REMOVE_ENCRYPTION_KEY (all_users=false) removes the current user's
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  894)  * claim to the key, then removes the key itself if no other users have claims.
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  895)  * FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS (all_users=true) always removes the
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  896)  * key itself.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  897)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  898)  * To "remove the key itself", first we wipe the actual master key secret, so
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  899)  * that no more inodes can be unlocked with it.  Then we try to evict all cached
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  900)  * inodes that had been unlocked with the key.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  901)  *
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  902)  * If all inodes were evicted, then we unlink the fscrypt_master_key from the
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  903)  * keyring.  Otherwise it remains in the keyring in the "incompletely removed"
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  904)  * state (without the actual secret key) where it tracks the list of remaining
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  905)  * inodes.  Userspace can execute the ioctl again later to retry eviction, or
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  906)  * alternatively can re-add the secret key again.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  907)  *
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  908)  * For more details, see the "Removing keys" section of
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  909)  * Documentation/filesystems/fscrypt.rst.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  910)  */
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  911) static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  912) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  913) 	struct super_block *sb = file_inode(filp)->i_sb;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  914) 	struct fscrypt_remove_key_arg __user *uarg = _uarg;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  915) 	struct fscrypt_remove_key_arg arg;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  916) 	struct key *key;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  917) 	struct fscrypt_master_key *mk;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  918) 	u32 status_flags = 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  919) 	int err;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  920) 	bool dead;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  921) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  922) 	if (copy_from_user(&arg, uarg, sizeof(arg)))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  923) 		return -EFAULT;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  924) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  925) 	if (!valid_key_spec(&arg.key_spec))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  926) 		return -EINVAL;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  927) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  928) 	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  929) 		return -EINVAL;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  930) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  931) 	/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  932) 	 * Only root can add and remove keys that are identified by an arbitrary
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  933) 	 * descriptor rather than by a cryptographic hash.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  934) 	 */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  935) 	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  936) 	    !capable(CAP_SYS_ADMIN))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  937) 		return -EACCES;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  938) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  939) 	/* Find the key being removed. */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  940) 	key = fscrypt_find_master_key(sb, &arg.key_spec);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  941) 	if (IS_ERR(key))
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  942) 		return PTR_ERR(key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  943) 	mk = key->payload.data[0];
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  944) 
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  945) 	down_write(&key->sem);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  946) 
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  947) 	/* If relevant, remove current user's (or all users) claim to the key */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  948) 	if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) {
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  949) 		if (all_users)
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  950) 			err = keyring_clear(mk->mk_users);
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  951) 		else
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700  952) 			err = remove_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  953) 		if (err) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  954) 			up_write(&key->sem);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  955) 			goto out_put_key;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  956) 		}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  957) 		if (mk->mk_users->keys.nr_leaves_on_tree != 0) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  958) 			/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  959) 			 * Other users have still added the key too.  We removed
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  960) 			 * the current user's claim to the key, but we still
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  961) 			 * can't remove the key itself.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  962) 			 */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  963) 			status_flags |=
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  964) 				FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  965) 			err = 0;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  966) 			up_write(&key->sem);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  967) 			goto out_put_key;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  968) 		}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  969) 	}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  970) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  971) 	/* No user claims remaining.  Go ahead and wipe the secret. */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  972) 	dead = false;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  973) 	if (is_master_key_secret_present(&mk->mk_secret)) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  974) 		wipe_master_key_secret(&mk->mk_secret);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  975) 		dead = refcount_dec_and_test(&mk->mk_refcount);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  976) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  977) 	up_write(&key->sem);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  978) 	if (dead) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  979) 		/*
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  980) 		 * No inodes reference the key, and we wiped the secret, so the
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  981) 		 * key object is free to be removed from the keyring.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  982) 		 */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  983) 		key_invalidate(key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  984) 		err = 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  985) 	} else {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  986) 		/* Some inodes still reference this key; try to evict them. */
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  987) 		err = try_to_lock_encrypted_files(sb, mk);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  988) 		if (err == -EBUSY) {
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  989) 			status_flags |=
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  990) 				FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  991) 			err = 0;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  992) 		}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  993) 	}
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  994) 	/*
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  995) 	 * We return 0 if we successfully did something: removed a claim to the
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  996) 	 * key, wiped the secret, or tried locking the files again.  Users need
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  997) 	 * to check the informational status flags if they care whether the key
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700  998) 	 * has been fully removed including all files locked.
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700  999) 	 */
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1000) out_put_key:
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1001) 	key_put(key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1002) 	if (err == 0)
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1003) 		err = put_user(status_flags, &uarg->removal_status_flags);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1004) 	return err;
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1005) }
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1006) 
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1007) int fscrypt_ioctl_remove_key(struct file *filp, void __user *uarg)
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1008) {
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1009) 	return do_remove_key(filp, uarg, false);
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1010) }
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1011) EXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key);
b1c0ec3599f42 (Eric Biggers     2019-08-04 19:35:46 -0700 1012) 
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1013) int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *uarg)
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1014) {
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1015) 	if (!capable(CAP_SYS_ADMIN))
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1016) 		return -EACCES;
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1017) 	return do_remove_key(filp, uarg, true);
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1018) }
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1019) EXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key_all_users);
78a1b96bcf7a0 (Eric Biggers     2019-08-04 19:35:47 -0700 1020) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1021) /*
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1022)  * Retrieve the status of an fscrypt master encryption key.
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1023)  *
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1024)  * We set ->status to indicate whether the key is absent, present, or
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1025)  * incompletely removed.  "Incompletely removed" means that the master key
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1026)  * secret has been removed, but some files which had been unlocked with it are
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1027)  * still in use.  This field allows applications to easily determine the state
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1028)  * of an encrypted directory without using a hack such as trying to open a
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1029)  * regular file in it (which can confuse the "incompletely removed" state with
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1030)  * absent or present).
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1031)  *
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1032)  * In addition, for v2 policy keys we allow applications to determine, via
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1033)  * ->status_flags and ->user_count, whether the key has been added by the
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1034)  * current user, by other users, or by both.  Most applications should not need
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1035)  * this, since ordinarily only one user should know a given key.  However, if a
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1036)  * secret key is shared by multiple users, applications may wish to add an
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1037)  * already-present key to prevent other users from removing it.  This ioctl can
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1038)  * be used to check whether that really is the case before the work is done to
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1039)  * add the key --- which might e.g. require prompting the user for a passphrase.
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1040)  *
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1041)  * For more details, see the "FS_IOC_GET_ENCRYPTION_KEY_STATUS" section of
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1042)  * Documentation/filesystems/fscrypt.rst.
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1043)  */
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1044) int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1045) {
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1046) 	struct super_block *sb = file_inode(filp)->i_sb;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1047) 	struct fscrypt_get_key_status_arg arg;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1048) 	struct key *key;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1049) 	struct fscrypt_master_key *mk;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1050) 	int err;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1051) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1052) 	if (copy_from_user(&arg, uarg, sizeof(arg)))
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1053) 		return -EFAULT;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1054) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1055) 	if (!valid_key_spec(&arg.key_spec))
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1056) 		return -EINVAL;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1057) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1058) 	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1059) 		return -EINVAL;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1060) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1061) 	arg.status_flags = 0;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1062) 	arg.user_count = 0;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1063) 	memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved));
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1064) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1065) 	key = fscrypt_find_master_key(sb, &arg.key_spec);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1066) 	if (IS_ERR(key)) {
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1067) 		if (key != ERR_PTR(-ENOKEY))
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1068) 			return PTR_ERR(key);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1069) 		arg.status = FSCRYPT_KEY_STATUS_ABSENT;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1070) 		err = 0;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1071) 		goto out;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1072) 	}
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1073) 	mk = key->payload.data[0];
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1074) 	down_read(&key->sem);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1075) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1076) 	if (!is_master_key_secret_present(&mk->mk_secret)) {
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1077) 		arg.status = FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1078) 		err = 0;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1079) 		goto out_release_key;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1080) 	}
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1081) 
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1082) 	arg.status = FSCRYPT_KEY_STATUS_PRESENT;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1083) 	if (mk->mk_users) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1084) 		struct key *mk_user;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1085) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1086) 		arg.user_count = mk->mk_users->keys.nr_leaves_on_tree;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1087) 		mk_user = find_master_key_user(mk);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1088) 		if (!IS_ERR(mk_user)) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1089) 			arg.status_flags |=
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1090) 				FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1091) 			key_put(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1092) 		} else if (mk_user != ERR_PTR(-ENOKEY)) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1093) 			err = PTR_ERR(mk_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1094) 			goto out_release_key;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1095) 		}
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1096) 	}
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1097) 	err = 0;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1098) out_release_key:
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1099) 	up_read(&key->sem);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1100) 	key_put(key);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1101) out:
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1102) 	if (!err && copy_to_user(uarg, &arg, sizeof(arg)))
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1103) 		err = -EFAULT;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1104) 	return err;
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1105) }
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1106) EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_key_status);
5a7e29924dac3 (Eric Biggers     2019-08-04 19:35:46 -0700 1107) 
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 1108) int __init fscrypt_init_keyring(void)
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 1109) {
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1110) 	int err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1111) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1112) 	err = register_key_type(&key_type_fscrypt);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1113) 	if (err)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1114) 		return err;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1115) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1116) 	err = register_key_type(&key_type_fscrypt_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1117) 	if (err)
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1118) 		goto err_unregister_fscrypt;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1119) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1120) 	err = register_key_type(&key_type_fscrypt_provisioning);
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1121) 	if (err)
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1122) 		goto err_unregister_fscrypt_user;
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1123) 
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1124) 	return 0;
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1125) 
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1126) err_unregister_fscrypt_user:
93edd392cad74 (Eric Biggers     2019-11-19 14:24:47 -0800 1127) 	unregister_key_type(&key_type_fscrypt_user);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1128) err_unregister_fscrypt:
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1129) 	unregister_key_type(&key_type_fscrypt);
23c688b54016e (Eric Biggers     2019-08-04 19:35:47 -0700 1130) 	return err;
22d94f493bfb4 (Eric Biggers     2019-08-04 19:35:46 -0700 1131) }