// SPDX-License-Identifier: GPL-2.0
/*
 * Filesystem-level keyring for fscrypt
 *
 * Copyright 2019 Google LLC
 */

/*
 * This file implements management of fscrypt master keys in the
 * filesystem-level keyring, including the ioctls:
 *
 * - FS_IOC_ADD_ENCRYPTION_KEY
 * - FS_IOC_REMOVE_ENCRYPTION_KEY
 * - FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS
 * - FS_IOC_GET_ENCRYPTION_KEY_STATUS
 *
 * See the "User API" section of Documentation/filesystems/fscrypt.rst for more
 * information about these ioctls.
 */

#include <crypto/skcipher.h>
#include <linux/export.h>
#include <linux/key-type.h>
#include <linux/once.h>
#include <linux/random.h>
#include <linux/seq_file.h>
#include <linux/unaligned.h>

#include "fscrypt_private.h"

/* The master encryption keys for a filesystem (->s_master_keys) */
struct fscrypt_keyring {
	/*
	 * Lock that protects ->key_hashtable.  It does *not* protect the
	 * fscrypt_master_key structs themselves.
	 */
	spinlock_t lock;

	/* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */
	struct hlist_head key_hashtable[128];
};

static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
{
	memzero_explicit(secret, sizeof(*secret));
}

static void move_master_key_secret(struct fscrypt_master_key_secret *dst,
				   struct fscrypt_master_key_secret *src)
{
	memcpy(dst, src, sizeof(*dst));
	memzero_explicit(src, sizeof(*src));
}

static void fscrypt_free_master_key(struct rcu_head *head)
{
	struct fscrypt_master_key *mk =
		container_of(head, struct fscrypt_master_key, mk_rcu_head);
	/*
	 * The master key secret and any embedded subkeys should have already
	 * been wiped when the last active reference to the fscrypt_master_key
	 * struct was dropped; doing it here would be unnecessarily late.
	 * Nevertheless, use kfree_sensitive() in case anything was missed.
	 */
	kfree_sensitive(mk);
}

static void clear_mk_users(struct fscrypt_master_key *mk);

void fscrypt_put_master_key(struct fscrypt_master_key *mk)
{
	if (!refcount_dec_and_test(&mk->mk_struct_refs))
		return;
	/*
	 * No structural references left, so clear ->mk_users, and also free the
	 * fscrypt_master_key struct itself after an RCU grace period ensures
	 * that concurrent keyring lookups can no longer find it.
	 */
	WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 0);
	clear_mk_users(mk);
	call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key);
}

void fscrypt_put_master_key_activeref(struct super_block *sb,
				      struct fscrypt_master_key *mk)
{
	struct fscrypt_mode_key *node, *tmp;

	if (!refcount_dec_and_test(&mk->mk_active_refs))
		return;
	/*
	 * No active references left, so complete the full removal of this
	 * fscrypt_master_key struct by removing it from the keyring and
	 * destroying any non-file-scoped subkeys.
	 */

	if (WARN_ON_ONCE(!sb->s_master_keys))
		return;
	spin_lock(&sb->s_master_keys->lock);
	hlist_del_rcu(&mk->mk_node);
	spin_unlock(&sb->s_master_keys->lock);

	/*
	 * ->mk_active_refs == 0 implies that ->mk_present is false and
	 * ->mk_decrypted_inodes is empty.
	 */
	WARN_ON_ONCE(mk->mk_present);
	WARN_ON_ONCE(!list_empty(&mk->mk_decrypted_inodes));

	/*
	 * Destroy any non-file-scoped subkeys.  Since ->mk_active_refs == 0,
	 * they're no longer referenced by any inodes.  Nor can key setup run
	 * and use them again.  So they're no longer needed.  (This implies no
	 * concurrent readers, so we don't need list_del_rcu() for example.)
	 */
	list_for_each_entry_safe(node, tmp, &mk->mk_mode_keys, link) {
		fscrypt_destroy_prepared_key(sb, &node->key);
		list_del(&node->link);
		kfree(node);
	}
	memzero_explicit(&mk->mk_ino_hash_key,
			 sizeof(mk->mk_ino_hash_key));
	mk->mk_ino_hash_key_initialized = false;

	/* Drop the structural ref associated with the active refs. */
	fscrypt_put_master_key(mk);
}

/*
 * This transitions the key state from present to incompletely removed, and then
 * potentially to absent (depending on whether inodes remain).
 */
static void fscrypt_initiate_key_removal(struct super_block *sb,
					 struct fscrypt_master_key *mk)
{
	WRITE_ONCE(mk->mk_present, false);
	wipe_master_key_secret(&mk->mk_secret);
	fscrypt_put_master_key_activeref(sb, mk);
}

static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
{
	if (spec->__reserved)
		return false;
	return master_key_spec_len(spec) != 0;
}

static int fscrypt_user_key_instantiate(struct key *key,
					struct key_preparsed_payload *prep)
{
	/*
	 * We just charge FSCRYPT_MAX_RAW_KEY_SIZE bytes to the user's key quota
	 * for each key, regardless of the exact key size.  The amount of memory
	 * actually used is greater than the size of the raw key anyway.
	 */
	return key_payload_reserve(key, FSCRYPT_MAX_RAW_KEY_SIZE);
}

static void fscrypt_user_key_describe(const struct key *key, struct seq_file *m)
{
	seq_puts(m, key->description);
}

/*
 * Type of fscrypt_master_key_user::quota_key.  This contains no secret; it
 * exists solely to charge a user's key quota.
 *
 * Note that the name of this key type really should be something like
 * ".fscrypt-user" instead of simply ".fscrypt".  But the shorter name is chosen
 * mainly for simplicity of presentation in /proc/keys when read by a non-root
 * user.  And it is expected to be rare that a key is actually added by multiple
 * users, since users should keep their encryption keys confidential.
 */
static struct key_type key_type_fscrypt_user = {
	.name			= ".fscrypt",
	.instantiate		= fscrypt_user_key_instantiate,
	.describe		= fscrypt_user_key_describe,
};

#define FSCRYPT_MK_USER_DESCRIPTION_SIZE	\
	(2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1)

/* Create ->s_master_keys if needed.  Synchronized by fscrypt_add_key_mutex. */
static int allocate_filesystem_keyring(struct super_block *sb)
{
	struct fscrypt_keyring *keyring;

	if (sb->s_master_keys)
		return 0;

	keyring = kzalloc_obj(*keyring);
	if (!keyring)
		return -ENOMEM;
	spin_lock_init(&keyring->lock);
	/*
	 * Pairs with the smp_load_acquire() in fscrypt_find_master_key().
	 * I.e., here we publish ->s_master_keys with a RELEASE barrier so that
	 * concurrent tasks can ACQUIRE it.
	 */
	smp_store_release(&sb->s_master_keys, keyring);
	return 0;
}

/*
 * Release all encryption keys that have been added to the filesystem, along
 * with the keyring that contains them.
 *
 * This is called at unmount time, after all potentially-encrypted inodes have
 * been evicted.  The filesystem's underlying block device(s) are still
 * available at this time; this is important because after user file accesses
 * have been allowed, this function may need to evict keys from the keyslots of
 * an inline crypto engine, which requires the block device(s).
 */
void fscrypt_destroy_keyring(struct super_block *sb)
{
	struct fscrypt_keyring *keyring = sb->s_master_keys;
	size_t i;

	if (!keyring)
		return;

	for (i = 0; i < ARRAY_SIZE(keyring->key_hashtable); i++) {
		struct hlist_head *bucket = &keyring->key_hashtable[i];
		struct fscrypt_master_key *mk;
		struct hlist_node *tmp;

		hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) {
			/*
			 * Since all potentially-encrypted inodes were already
			 * evicted, every key remaining in the keyring should
			 * have an empty inode list, and should only still be in
			 * the keyring due to the single active ref associated
			 * with ->mk_present.  There should be no structural
			 * refs beyond the one associated with the active ref.
			 */
			WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 1);
			WARN_ON_ONCE(refcount_read(&mk->mk_struct_refs) != 1);
			WARN_ON_ONCE(!mk->mk_present);
			fscrypt_initiate_key_removal(sb, mk);
		}
	}
	kfree_sensitive(keyring);
	sb->s_master_keys = NULL;
}

static struct hlist_head *
fscrypt_mk_hash_bucket(struct fscrypt_keyring *keyring,
		       const struct fscrypt_key_specifier *mk_spec)
{
	/*
	 * Since key specifiers should be "random" values, it is sufficient to
	 * use a trivial hash function that just takes the first several bits of
	 * the key specifier.
	 */
	unsigned long i = get_unaligned((unsigned long *)&mk_spec->u);

	return &keyring->key_hashtable[i % ARRAY_SIZE(keyring->key_hashtable)];
}

/*
 * Find the specified master key struct in ->s_master_keys and take a structural
 * ref to it.  The structural ref guarantees that the key struct continues to
 * exist, but it does *not* guarantee that ->s_master_keys continues to contain
 * the key struct.  The structural ref needs to be dropped by
 * fscrypt_put_master_key().  Returns NULL if the key struct is not found.
 */
struct fscrypt_master_key *
fscrypt_find_master_key(struct super_block *sb,
			const struct fscrypt_key_specifier *mk_spec)
{
	struct fscrypt_keyring *keyring;
	struct hlist_head *bucket;
	struct fscrypt_master_key *mk;

	/*
	 * Pairs with the smp_store_release() in allocate_filesystem_keyring().
	 * I.e., another task can publish ->s_master_keys concurrently,
	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
	 * to safely ACQUIRE the memory the other task published.
	 */
	keyring = smp_load_acquire(&sb->s_master_keys);
	if (keyring == NULL)
		return NULL; /* No keyring yet, so no keys yet. */

	bucket = fscrypt_mk_hash_bucket(keyring, mk_spec);
	rcu_read_lock();
	switch (mk_spec->type) {
	case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR:
		hlist_for_each_entry_rcu(mk, bucket, mk_node) {
			if (mk->mk_spec.type ==
				FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
			    memcmp(mk->mk_spec.u.descriptor,
				   mk_spec->u.descriptor,
				   FSCRYPT_KEY_DESCRIPTOR_SIZE) == 0 &&
			    refcount_inc_not_zero(&mk->mk_struct_refs))
				goto out;
		}
		break;
	case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER:
		hlist_for_each_entry_rcu(mk, bucket, mk_node) {
			if (mk->mk_spec.type ==
				FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER &&
			    memcmp(mk->mk_spec.u.identifier,
				   mk_spec->u.identifier,
				   FSCRYPT_KEY_IDENTIFIER_SIZE) == 0 &&
			    refcount_inc_not_zero(&mk->mk_struct_refs))
				goto out;
		}
		break;
	}
	mk = NULL;
out:
	rcu_read_unlock();
	return mk;
}

/* Find the current user's claim in ->mk_users.  ->mk_sem must be held. */
static struct fscrypt_master_key_user *
find_master_key_user(struct fscrypt_master_key *mk)
{
	struct fscrypt_master_key_user *mk_user;
	kuid_t uid = current_fsuid();

	list_for_each_entry(mk_user, &mk->mk_users, link) {
		if (uid_eq(mk_user->uid, uid))
			return mk_user;
	}
	return NULL;
}

/*
 * Give the current user a claim in ->mk_users.  This charges the user's quota
 * and marks the master key as added by the current user, so that it cannot be
 * removed by another user with the key.  Either ->mk_sem must be held for
 * write, or the master key must be still undergoing initialization.
 */
static int add_master_key_user(struct fscrypt_master_key *mk)
{
	kuid_t uid = current_fsuid();
	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
	struct key *quota_key;
	struct fscrypt_master_key_user *mk_user;
	int err;

	snprintf(description, sizeof(description), "%*phN.uid.%u",
		 FSCRYPT_KEY_IDENTIFIER_SIZE, mk->mk_spec.u.identifier,
		 __kuid_val(uid));
	quota_key = key_alloc(&key_type_fscrypt_user, description, uid,
			      current_gid(), current_cred(),
			      KEY_POS_SEARCH | KEY_USR_VIEW, 0, NULL);
	if (IS_ERR(quota_key))
		return PTR_ERR(quota_key);

	err = key_instantiate_and_link(quota_key, NULL, 0, NULL, NULL);
	if (err) {
		key_put(quota_key);
		return err;
	}

	mk_user = kzalloc_obj(*mk_user);
	if (!mk_user) {
		key_put(quota_key);
		return -ENOMEM;
	}
	mk_user->uid = uid;
	mk_user->quota_key = quota_key;
	list_add(&mk_user->link, &mk->mk_users);
	return 0;
}

static void unlink_and_free_mk_user(struct fscrypt_master_key_user *mk_user)
{
	list_del(&mk_user->link);
	key_put(mk_user->quota_key);
	kfree(mk_user);
}

/*
 * Remove the current user's claim from ->mk_users.
 * ->mk_sem must be held for write.
 *
 * Returns 0 if removed or -ENOKEY if not found.
 */
static int remove_master_key_user(struct fscrypt_master_key *mk)
{
	struct fscrypt_master_key_user *mk_user;

	mk_user = find_master_key_user(mk);
	if (!mk_user)
		return -ENOKEY;
	unlink_and_free_mk_user(mk_user);
	return 0;
}

/*
 * Clear ->mk_users.  Either ->mk_sem must be held for write, or 'mk' must have
 * no structural references left.
 */
static void clear_mk_users(struct fscrypt_master_key *mk)
{
	struct fscrypt_master_key_user *mk_user, *tmp;

	list_for_each_entry_safe(mk_user, tmp, &mk->mk_users, link)
		unlink_and_free_mk_user(mk_user);
}

/*
 * Allocate a new fscrypt_master_key, transfer the given secret over to it, and
 * insert it into sb->s_master_keys.
 */
static int add_new_master_key(struct super_block *sb,
			      struct fscrypt_master_key_secret *secret,
			      const struct fscrypt_key_specifier *mk_spec)
{
	struct fscrypt_keyring *keyring = sb->s_master_keys;
	struct fscrypt_master_key *mk;
	int err;

	mk = kzalloc_obj(*mk);
	if (!mk)
		return -ENOMEM;

	init_rwsem(&mk->mk_sem);
	refcount_set(&mk->mk_struct_refs, 1);
	mk->mk_spec = *mk_spec;

	INIT_LIST_HEAD(&mk->mk_users);

	INIT_LIST_HEAD(&mk->mk_decrypted_inodes);
	spin_lock_init(&mk->mk_decrypted_inodes_lock);

	INIT_LIST_HEAD(&mk->mk_mode_keys);

	if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
		err = add_master_key_user(mk);
		if (err)
			goto out_put;
	}

	move_master_key_secret(&mk->mk_secret, secret);
	mk->mk_present = true;
	refcount_set(&mk->mk_active_refs, 1); /* ->mk_present is true */

	spin_lock(&keyring->lock);
	hlist_add_head_rcu(&mk->mk_node,
			   fscrypt_mk_hash_bucket(keyring, mk_spec));
	spin_unlock(&keyring->lock);
	return 0;

out_put:
	fscrypt_put_master_key(mk);
	return err;
}

#define KEY_DEAD	1

static int add_existing_master_key(struct fscrypt_master_key *mk,
				   struct fscrypt_master_key_secret *secret)
{
	int err;

	/*
	 * For v2 policy keys (FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER): If the current
	 * user is already in ->mk_users, then there's nothing to do.
	 * Otherwise, add the user to ->mk_users.
	 */
	if (mk->mk_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
		if (find_master_key_user(mk) != NULL)
			return 0;
		err = add_master_key_user(mk);
		if (err)
			return err;
	}

	/* If the key is incompletely removed, make it present again. */
	if (!mk->mk_present) {
		if (!refcount_inc_not_zero(&mk->mk_active_refs)) {
			/*
			 * Raced with the last active ref being dropped, so the
			 * key has become, or is about to become, "absent".
			 * Therefore, we need to allocate a new key struct.
			 */
			return KEY_DEAD;
		}
		move_master_key_secret(&mk->mk_secret, secret);
		WRITE_ONCE(mk->mk_present, true);
	}

	return 0;
}

static int do_add_master_key(struct super_block *sb,
			     struct fscrypt_master_key_secret *secret,
			     const struct fscrypt_key_specifier *mk_spec)
{
	static DEFINE_MUTEX(fscrypt_add_key_mutex);
	struct fscrypt_master_key *mk;
	int err;

	guard(mutex)(&fscrypt_add_key_mutex); /* serialize find + link */

	mk = fscrypt_find_master_key(sb, mk_spec);
	if (!mk) {
		/* Didn't find the key in ->s_master_keys.  Add it. */
		err = allocate_filesystem_keyring(sb);
		if (!err)
			err = add_new_master_key(sb, secret, mk_spec);
	} else {
		/*
		 * Found the key in ->s_master_keys.  Add the user to ->mk_users
		 * if needed, and make the key "present" again if possible.
		 */
		down_write(&mk->mk_sem);
		err = add_existing_master_key(mk, secret);
		up_write(&mk->mk_sem);
		if (err == KEY_DEAD) {
			/*
			 * We found a key struct, but it's already been fully
			 * removed.  Ignore the old struct and add a new one.
			 * fscrypt_add_key_mutex means we don't need to worry
			 * about concurrent adds.
			 */
			err = add_new_master_key(sb, secret, mk_spec);
		}
		fscrypt_put_master_key(mk);
	}
	return err;
}

static int add_master_key(struct super_block *sb,
			  struct fscrypt_master_key_secret *secret,
			  struct fscrypt_key_specifier *key_spec)
{
	int err;

	if (key_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
		u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE];
		u8 *kdf_key = secret->bytes;
		unsigned int kdf_key_size = secret->size;
		u8 keyid_kdf_ctx = HKDF_CONTEXT_KEY_IDENTIFIER_FOR_RAW_KEY;

		/*
		 * For raw keys, the fscrypt master key is used directly as the
		 * fscrypt KDF key.  For hardware-wrapped keys, we have to pass
		 * the master key to the hardware to derive the KDF key, which
		 * is then only used to derive non-file-contents subkeys.
		 */
		if (secret->is_hw_wrapped) {
			err = fscrypt_derive_sw_secret(sb, secret->bytes,
						       secret->size, sw_secret);
			if (err)
				return err;
			kdf_key = sw_secret;
			kdf_key_size = sizeof(sw_secret);
			/*
			 * To avoid weird behavior if someone manages to
			 * determine sw_secret and add it as a raw key, ensure
			 * that hardware-wrapped keys and raw keys will have
			 * different key identifiers by deriving their key
			 * identifiers using different KDF contexts.
			 */
			keyid_kdf_ctx =
				HKDF_CONTEXT_KEY_IDENTIFIER_FOR_HW_WRAPPED_KEY;
		}
		fscrypt_init_hkdf(&secret->hkdf, kdf_key, kdf_key_size);
		/*
		 * Now that the KDF context is initialized, the raw KDF key is
		 * no longer needed.
		 */
		memzero_explicit(kdf_key, kdf_key_size);

		/* Calculate the key identifier */
		fscrypt_hkdf_expand(&secret->hkdf, keyid_kdf_ctx, NULL, 0,
				    key_spec->u.identifier,
				    FSCRYPT_KEY_IDENTIFIER_SIZE);
	}
	return do_add_master_key(sb, secret, key_spec);
}

/*
 * Validate the size of an fscrypt master key being added.  Note that this is
 * just an initial check, as we don't know which ciphers will be used yet.
 * There is a stricter size check later when the key is actually used by a file.
 */
static inline bool fscrypt_valid_key_size(size_t size, u32 add_key_flags)
{
	u32 max_size = (add_key_flags & FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED) ?
		       FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE :
		       FSCRYPT_MAX_RAW_KEY_SIZE;

	return size >= FSCRYPT_MIN_KEY_SIZE && size <= max_size;
}

static int fscrypt_provisioning_key_preparse(struct key_preparsed_payload *prep)
{
	const struct fscrypt_provisioning_key_payload *payload = prep->data;

	if (prep->datalen < sizeof(*payload))
		return -EINVAL;

	if (!fscrypt_valid_key_size(prep->datalen - sizeof(*payload),
				    payload->flags))
		return -EINVAL;

	if (payload->type != FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
	    payload->type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER)
		return -EINVAL;

	if (payload->flags & ~FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED)
		return -EINVAL;

	prep->payload.data[0] = kmemdup(payload, prep->datalen, GFP_KERNEL);
	if (!prep->payload.data[0])
		return -ENOMEM;

	prep->quotalen = prep->datalen;
	return 0;
}

static void fscrypt_provisioning_key_free_preparse(
					struct key_preparsed_payload *prep)
{
	kfree_sensitive(prep->payload.data[0]);
}

static void fscrypt_provisioning_key_describe(const struct key *key,
					      struct seq_file *m)
{
	seq_puts(m, key->description);
	if (key_is_positive(key)) {
		const struct fscrypt_provisioning_key_payload *payload =
			key->payload.data[0];

		seq_printf(m, ": %u [%u]", key->datalen, payload->type);
	}
}

static void fscrypt_provisioning_key_destroy(struct key *key)
{
	kfree_sensitive(key->payload.data[0]);
}

static struct key_type key_type_fscrypt_provisioning = {
	.name			= "fscrypt-provisioning",
	.preparse		= fscrypt_provisioning_key_preparse,
	.free_preparse		= fscrypt_provisioning_key_free_preparse,
	.instantiate		= generic_key_instantiate,
	.describe		= fscrypt_provisioning_key_describe,
	.destroy		= fscrypt_provisioning_key_destroy,
};

/*
 * Retrieve the key from the Linux keyring key specified by 'key_id', and store
 * it into 'secret'.
 *
 * The key must be of type "fscrypt-provisioning" and must have the 'type' and
 * 'flags' field of the payload set to the given values, indicating that the key
 * is intended for use for the specified purpose.  We don't use the "logon" key
 * type because there's no way to completely restrict the use of such keys; they
 * can be used by any kernel API that accepts "logon" keys and doesn't require a
 * specific service prefix.
 *
 * The ability to specify the key via Linux keyring key is intended for cases
 * where userspace needs to re-add keys after the filesystem is unmounted and
 * re-mounted.  Most users should just provide the key directly instead.
 */
static int get_keyring_key(u32 key_id, u32 type, u32 flags,
			   struct fscrypt_master_key_secret *secret)
{
	key_ref_t ref;
	struct key *key;
	const struct fscrypt_provisioning_key_payload *payload;
	int err;

	ref = lookup_user_key(key_id, 0, KEY_NEED_SEARCH);
	if (IS_ERR(ref))
		return PTR_ERR(ref);
	key = key_ref_to_ptr(ref);

	if (key->type != &key_type_fscrypt_provisioning)
		goto bad_key;
	payload = key->payload.data[0];

	/*
	 * Don't allow fscrypt v1 keys to be used as v2 keys and vice versa.
	 * Similarly, don't allow hardware-wrapped keys to be used as
	 * non-hardware-wrapped keys and vice versa.
	 */
	if (payload->type != type || payload->flags != flags)
		goto bad_key;

	secret->size = key->datalen - sizeof(*payload);
	memcpy(secret->bytes, payload->raw, secret->size);
	err = 0;
	goto out_put;

bad_key:
	err = -EKEYREJECTED;
out_put:
	key_ref_put(ref);
	return err;
}

/*
 * Add a master encryption key to the filesystem, causing all files which were
 * encrypted with it to appear "unlocked" (decrypted) when accessed.
 *
 * When adding a key for use by v1 encryption policies, this ioctl is
 * privileged, and userspace must provide the 'key_descriptor'.
 *
 * When adding a key for use by v2+ encryption policies, this ioctl is
 * unprivileged.  This is needed, in general, to allow non-root users to use
 * encryption without encountering the visibility problems of process-subscribed
 * keyrings and the inability to properly remove keys.  This works by having
 * each key identified by its cryptographically secure hash --- the
 * 'key_identifier'.  The cryptographic hash ensures that a malicious user
 * cannot add the wrong key for a given identifier.  Furthermore, each added key
 * is charged to the appropriate user's quota for the keyrings service, which
 * prevents a malicious user from adding too many keys.  Finally, we forbid a
 * user from removing a key while other users have added it too, which prevents
 * a user who knows another user's key from causing a denial-of-service by
 * removing it at an inopportune time.  (We tolerate that a user who knows a key
 * can prevent other users from removing it.)
 *
 * For more details, see the "FS_IOC_ADD_ENCRYPTION_KEY" section of
 * Documentation/filesystems/fscrypt.rst.
 */
int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg)
{
	struct super_block *sb = file_inode(filp)->i_sb;
	struct fscrypt_add_key_arg __user *uarg = _uarg;
	struct fscrypt_add_key_arg arg;
	struct fscrypt_master_key_secret secret;
	int err;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (!valid_key_spec(&arg.key_spec))
		return -EINVAL;

	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
		return -EINVAL;

	/*
	 * Only root can add keys that are identified by an arbitrary descriptor
	 * rather than by a cryptographic hash --- since otherwise a malicious
	 * user could add the wrong key.
	 */
	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
	    !capable(CAP_SYS_ADMIN))
		return -EACCES;

	memset(&secret, 0, sizeof(secret));

	if (arg.flags) {
		if (arg.flags & ~FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED)
			return -EINVAL;
		if (arg.key_spec.type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER)
			return -EINVAL;
		secret.is_hw_wrapped = true;
	}

	if (arg.key_id) {
		if (arg.raw_size != 0)
			return -EINVAL;
		err = get_keyring_key(arg.key_id, arg.key_spec.type, arg.flags,
				      &secret);
		if (err)
			goto out_wipe_secret;
	} else {
		if (!fscrypt_valid_key_size(arg.raw_size, arg.flags))
			return -EINVAL;
		secret.size = arg.raw_size;
		err = -EFAULT;
		if (copy_from_user(secret.bytes, uarg->raw, secret.size))
			goto out_wipe_secret;
	}

	err = add_master_key(sb, &secret, &arg.key_spec);
	if (err)
		goto out_wipe_secret;

	/* Return the key identifier to userspace, if applicable */
	err = -EFAULT;
	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER &&
	    copy_to_user(uarg->key_spec.u.identifier, arg.key_spec.u.identifier,
			 FSCRYPT_KEY_IDENTIFIER_SIZE))
		goto out_wipe_secret;
	err = 0;
out_wipe_secret:
	wipe_master_key_secret(&secret);
	return err;
}
EXPORT_SYMBOL_GPL(fscrypt_ioctl_add_key);

static void
fscrypt_get_test_dummy_secret(struct fscrypt_master_key_secret *secret)
{
	static u8 test_key[FSCRYPT_MAX_RAW_KEY_SIZE];

	get_random_once(test_key, sizeof(test_key));

	memset(secret, 0, sizeof(*secret));
	secret->size = sizeof(test_key);
	memcpy(secret->bytes, test_key, sizeof(test_key));
}

void fscrypt_get_test_dummy_key_identifier(
				u8 key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
{
	struct fscrypt_master_key_secret secret;

	fscrypt_get_test_dummy_secret(&secret);
	fscrypt_init_hkdf(&secret.hkdf, secret.bytes, secret.size);
	fscrypt_hkdf_expand(&secret.hkdf,
			    HKDF_CONTEXT_KEY_IDENTIFIER_FOR_RAW_KEY, NULL, 0,
			    key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
	wipe_master_key_secret(&secret);
}

/**
 * fscrypt_add_test_dummy_key() - add the test dummy encryption key
 * @sb: the filesystem instance to add the key to
 * @key_spec: the key specifier of the test dummy encryption key
 *
 * Add the key for the test_dummy_encryption mount option to the filesystem.  To
 * prevent misuse of this mount option, a per-boot random key is used instead of
 * a hardcoded one.  This makes it so that any encrypted files created using
 * this option won't be accessible after a reboot.
 *
 * Return: 0 on success, -errno on failure
 */
int fscrypt_add_test_dummy_key(struct super_block *sb,
			       struct fscrypt_key_specifier *key_spec)
{
	struct fscrypt_master_key_secret secret;
	int err;

	fscrypt_get_test_dummy_secret(&secret);
	err = add_master_key(sb, &secret, key_spec);
	wipe_master_key_secret(&secret);
	return err;
}

/*
 * Verify that the current user has added a master key with the given identifier
 * (returns -ENOKEY if not).  This is needed to prevent a user from encrypting
 * their files using some other user's key which they don't actually know.
 * Cryptographically this isn't much of a problem, but the semantics of this
 * would be a bit weird, so it's best to just forbid it.
 *
 * The system administrator (CAP_FOWNER) can override this, which should be
 * enough for any use cases where encryption policies are being set using keys
 * that were chosen ahead of time but aren't available at the moment.
 *
 * Note that the key may have already removed by the time this returns, but
 * that's okay; we just care whether the key was there at some point.
 *
 * Return: 0 if the key is added, -ENOKEY if it isn't, or another -errno code
 */
int fscrypt_verify_key_added(struct super_block *sb,
			     const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
{
	struct fscrypt_key_specifier mk_spec;
	struct fscrypt_master_key *mk;
	int err;

	mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
	memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);

	mk = fscrypt_find_master_key(sb, &mk_spec);
	if (!mk) {
		err = -ENOKEY;
		goto out;
	}
	down_read(&mk->mk_sem);
	if (find_master_key_user(mk) != NULL)
		err = 0;
	else
		err = -ENOKEY;
	up_read(&mk->mk_sem);
	fscrypt_put_master_key(mk);
out:
	if (err == -ENOKEY && capable(CAP_FOWNER))
		err = 0;
	return err;
}

/*
 * Try to evict the inode's dentries from the dentry cache.  If the inode is a
 * directory, then it can have at most one dentry; however, that dentry may be
 * pinned by child dentries, so first try to evict the children too.
 */
static void shrink_dcache_inode(struct inode *inode)
{
	struct dentry *dentry;

	if (S_ISDIR(inode->i_mode)) {
		dentry = d_find_any_alias(inode);
		if (dentry) {
			shrink_dcache_parent(dentry);
			dput(dentry);
		}
	}
	d_prune_aliases(inode);
}

static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk)
{
	struct fscrypt_inode_info *ci;
	struct inode *inode;
	struct inode *toput_inode = NULL;

	spin_lock(&mk->mk_decrypted_inodes_lock);

	list_for_each_entry(ci, &mk->mk_decrypted_inodes, ci_master_key_link) {
		inode = ci->ci_inode;
		spin_lock(&inode->i_lock);
		if (inode_state_read(inode) & (I_FREEING | I_WILL_FREE | I_NEW)) {
			spin_unlock(&inode->i_lock);
			continue;
		}
		__iget(inode);
		spin_unlock(&inode->i_lock);
		spin_unlock(&mk->mk_decrypted_inodes_lock);

		shrink_dcache_inode(inode);
		iput(toput_inode);
		toput_inode = inode;

		spin_lock(&mk->mk_decrypted_inodes_lock);
	}

	spin_unlock(&mk->mk_decrypted_inodes_lock);
	iput(toput_inode);
}

static int check_for_busy_inodes(struct super_block *sb,
				 struct fscrypt_master_key *mk)
{
	struct list_head *pos;
	size_t busy_count = 0;
	char ino_str[50] = "";
	u64 ino;

	spin_lock(&mk->mk_decrypted_inodes_lock);

	list_for_each(pos, &mk->mk_decrypted_inodes)
		busy_count++;

	if (busy_count == 0) {
		spin_unlock(&mk->mk_decrypted_inodes_lock);
		return 0;
	}

	{
		/* select an example file to show for debugging purposes */
		struct inode *inode =
			list_first_entry(&mk->mk_decrypted_inodes,
					 struct fscrypt_inode_info,
					 ci_master_key_link)->ci_inode;
		ino = inode->i_ino;
	}
	spin_unlock(&mk->mk_decrypted_inodes_lock);

	/* If the inode is currently being created, ino may still be 0. */
	if (ino)
		snprintf(ino_str, sizeof(ino_str), ", including ino %llu", ino);

	fscrypt_warn(NULL,
		     "%s: %zu inode(s) still busy after removing key with %s %*phN%s",
		     sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec),
		     master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u,
		     ino_str);
	return -EBUSY;
}

static int try_to_lock_encrypted_files(struct super_block *sb,
				       struct fscrypt_master_key *mk)
{
	int err1;
	int err2;

	/*
	 * An inode can't be evicted while it is dirty or has dirty pages.
	 * Thus, we first have to clean the inodes in ->mk_decrypted_inodes.
	 *
	 * Just do it the easy way: call sync_filesystem().  It's overkill, but
	 * it works, and it's more important to minimize the amount of caches we
	 * drop than the amount of data we sync.  Also, unprivileged users can
	 * already call sync_filesystem() via sys_syncfs() or sys_sync().
	 */
	down_read(&sb->s_umount);
	err1 = sync_filesystem(sb);
	up_read(&sb->s_umount);
	/* If a sync error occurs, still try to evict as much as possible. */

	/*
	 * Inodes are pinned by their dentries, so we have to evict their
	 * dentries.  shrink_dcache_sb() would suffice, but would be overkill
	 * and inappropriate for use by unprivileged users.  So instead go
	 * through the inodes' alias lists and try to evict each dentry.
	 */
	evict_dentries_for_decrypted_inodes(mk);

	/*
	 * evict_dentries_for_decrypted_inodes() already iput() each inode in
	 * the list; any inodes for which that dropped the last reference will
	 * have been evicted due to fscrypt_drop_inode() detecting the key
	 * removal and telling the VFS to evict the inode.  So to finish, we
	 * just need to check whether any inodes couldn't be evicted.
	 */
	err2 = check_for_busy_inodes(sb, mk);

	return err1 ?: err2;
}

/*
 * Try to remove an fscrypt master encryption key.
 *
 * FS_IOC_REMOVE_ENCRYPTION_KEY (all_users=false) removes the current user's
 * claim to the key, then removes the key itself if no other users have claims.
 * FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS (all_users=true) always removes the
 * key itself.
 *
 * To "remove the key itself", first we transition the key to the "incompletely
 * removed" state, so that no more inodes can be unlocked with it.  Then we try
 * to evict all cached inodes that had been unlocked with the key.
 *
 * If all inodes were evicted, then we unlink the fscrypt_master_key from the
 * keyring.  Otherwise it remains in the keyring in the "incompletely removed"
 * state where it tracks the list of remaining inodes.  Userspace can execute
 * the ioctl again later to retry eviction, or alternatively can re-add the key.
 *
 * For more details, see the "Removing keys" section of
 * Documentation/filesystems/fscrypt.rst.
 */
static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
{
	struct super_block *sb = file_inode(filp)->i_sb;
	struct fscrypt_remove_key_arg __user *uarg = _uarg;
	struct fscrypt_remove_key_arg arg;
	struct fscrypt_master_key *mk;
	u32 status_flags = 0;
	int err;
	bool inodes_remain;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (!valid_key_spec(&arg.key_spec))
		return -EINVAL;

	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
		return -EINVAL;

	/*
	 * Only root can add and remove keys that are identified by an arbitrary
	 * descriptor rather than by a cryptographic hash.
	 */
	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
	    !capable(CAP_SYS_ADMIN))
		return -EACCES;

	/* Find the key being removed. */
	mk = fscrypt_find_master_key(sb, &arg.key_spec);
	if (!mk)
		return -ENOKEY;
	down_write(&mk->mk_sem);

	/* If relevant, remove current user's (or all users) claim to the key */
	if (!list_empty(&mk->mk_users)) {
		if (all_users) {
			clear_mk_users(mk);
			err = 0;
		} else {
			err = remove_master_key_user(mk);
		}
		if (err) {
			up_write(&mk->mk_sem);
			goto out_put_key;
		}
		if (!list_empty(&mk->mk_users)) {
			/*
			 * Other users have still added the key too.  We removed
			 * the current user's claim to the key, but we still
			 * can't remove the key itself.
			 */
			status_flags |=
				FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS;
			err = 0;
			up_write(&mk->mk_sem);
			goto out_put_key;
		}
	}

	/* No user claims remaining.  Initiate removal of the key. */
	err = -ENOKEY;
	if (mk->mk_present) {
		fscrypt_initiate_key_removal(sb, mk);
		err = 0;
	}
	inodes_remain = refcount_read(&mk->mk_active_refs) > 0;
	up_write(&mk->mk_sem);

	if (inodes_remain) {
		/* Some inodes still reference this key; try to evict them. */
		err = try_to_lock_encrypted_files(sb, mk);
		if (err == -EBUSY) {
			status_flags |=
				FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY;
			err = 0;
		}
	}
	/*
	 * We return 0 if we successfully did something: removed a claim to the
	 * key, initiated removal of the key, or tried locking the files again.
	 * Users need to check the informational status flags if they care
	 * whether the key has been fully removed including all files locked.
	 */
out_put_key:
	fscrypt_put_master_key(mk);
	if (err == 0)
		err = put_user(status_flags, &uarg->removal_status_flags);
	return err;
}

int fscrypt_ioctl_remove_key(struct file *filp, void __user *uarg)
{
	return do_remove_key(filp, uarg, false);
}
EXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key);

int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *uarg)
{
	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
	return do_remove_key(filp, uarg, true);
}
EXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key_all_users);

/*
 * Retrieve the status of an fscrypt master encryption key.
 *
 * We set ->status to indicate whether the key is absent, present, or
 * incompletely removed.  (For an explanation of what these statuses mean and
 * how they are represented internally, see struct fscrypt_master_key.)  This
 * field allows applications to easily determine the status of an encrypted
 * directory without using a hack such as trying to open a regular file in it
 * (which can confuse the "incompletely removed" status with absent or present).
 *
 * In addition, for v2 policy keys we allow applications to determine, via
 * ->status_flags and ->user_count, whether the key has been added by the
 * current user, by other users, or by both.  Most applications should not need
 * this, since ordinarily only one user should know a given key.  However, if a
 * secret key is shared by multiple users, applications may wish to add an
 * already-present key to prevent other users from removing it.  This ioctl can
 * be used to check whether that really is the case before the work is done to
 * add the key --- which might e.g. require prompting the user for a passphrase.
 *
 * For more details, see the "FS_IOC_GET_ENCRYPTION_KEY_STATUS" section of
 * Documentation/filesystems/fscrypt.rst.
 */
int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
{
	struct super_block *sb = file_inode(filp)->i_sb;
	struct fscrypt_get_key_status_arg arg;
	struct fscrypt_master_key *mk;
	kuid_t uid;
	const struct fscrypt_master_key_user *mk_user;
	int err;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (!valid_key_spec(&arg.key_spec))
		return -EINVAL;

	if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved)))
		return -EINVAL;

	arg.status_flags = 0;
	arg.user_count = 0;
	memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved));

	mk = fscrypt_find_master_key(sb, &arg.key_spec);
	if (!mk) {
		arg.status = FSCRYPT_KEY_STATUS_ABSENT;
		err = 0;
		goto out;
	}
	down_read(&mk->mk_sem);

	if (!mk->mk_present) {
		arg.status = refcount_read(&mk->mk_active_refs) > 0 ?
			FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED :
			FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */;
		err = 0;
		goto out_release_key;
	}

	arg.status = FSCRYPT_KEY_STATUS_PRESENT;

	uid = current_fsuid();
	list_for_each_entry(mk_user, &mk->mk_users, link) {
		arg.user_count++;
		if (uid_eq(mk_user->uid, uid))
			arg.status_flags |=
				FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF;
	}
	err = 0;
out_release_key:
	up_read(&mk->mk_sem);
	fscrypt_put_master_key(mk);
out:
	if (!err && copy_to_user(uarg, &arg, sizeof(arg)))
		err = -EFAULT;
	return err;
}
EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_key_status);

void __init fscrypt_init_keyring(void)
{
	int err;

	/*
	 * Note that register_key_type() fails only if a key type with the same
	 * name already exists, which should never happen here.
	 */
	err = register_key_type(&key_type_fscrypt_user);
	if (err)
		panic("failed to register .fscrypt key type (%d)", err);
	err = register_key_type(&key_type_fscrypt_provisioning);
	if (err)
		panic("failed to register fscrypt-provisioning key type (%d)",
		      err);
}
