// 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 <asm/unaligned.h>
#include <crypto/skcipher.h>
#include <linux/key-type.h>
#include <linux/random.h>
#include <linux/seq_file.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)
{
	fscrypt_destroy_hkdf(&secret->hkdf);
	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);
}

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 free ->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);
	key_put(mk->mk_users);
	mk->mk_users = NULL;
	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)
{
	size_t i;

	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 subkeys embedded in it.
	 */

	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));

	for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
		fscrypt_destroy_prepared_key(
				sb, &mk->mk_direct_keys[i]);
		fscrypt_destroy_prepared_key(
				sb, &mk->mk_iv_ino_lblk_64_keys[i]);
		fscrypt_destroy_prepared_key(
				sb, &mk->mk_iv_ino_lblk_32_keys[i]);
	}
	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_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_KEY_SIZE);
}

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

/*
 * Type of key in ->mk_users.  Each key of this type represents a particular
 * user who has added a particular master key.
 *
 * 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_USERS_DESCRIPTION_SIZE	\
	(CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \
	 CONST_STRLEN("-users") + 1)

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

static void format_mk_users_keyring_description(
			char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE],
			const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
{
	sprintf(description, "fscrypt-%*phN-users",
		FSCRYPT_KEY_IDENTIFIER_SIZE, mk_identifier);
}

static void format_mk_user_description(
			char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE],
			const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
{

	sprintf(description, "%*phN.uid.%u", FSCRYPT_KEY_IDENTIFIER_SIZE,
		mk_identifier, __kuid_val(current_fsuid()));
}

/* 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(sizeof(*keyring), GFP_KERNEL);
	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;
}

static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
{
	char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE];
	struct key *keyring;

	format_mk_users_keyring_description(description,
					    mk->mk_spec.u.identifier);
	keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
				current_cred(), KEY_POS_SEARCH |
				  KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW,
				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
	if (IS_ERR(keyring))
		return PTR_ERR(keyring);

	mk->mk_users = keyring;
	return 0;
}

/*
 * Find the current user's "key" in the master key's ->mk_users.
 * Returns ERR_PTR(-ENOKEY) if not found.
 */
static struct key *find_master_key_user(struct fscrypt_master_key *mk)
{
	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
	key_ref_t keyref;

	format_mk_user_description(description, mk->mk_spec.u.identifier);

	/*
	 * We need to mark the keyring reference as "possessed" so that we
	 * acquire permission to search it, via the KEY_POS_SEARCH permission.
	 */
	keyref = keyring_search(make_key_ref(mk->mk_users, true /*possessed*/),
				&key_type_fscrypt_user, description, false);
	if (IS_ERR(keyref)) {
		if (PTR_ERR(keyref) == -EAGAIN || /* not found */
		    PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
			keyref = ERR_PTR(-ENOKEY);
		return ERR_CAST(keyref);
	}
	return key_ref_to_ptr(keyref);
}

/*
 * Give the current user a "key" 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)
{
	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
	struct key *mk_user;
	int err;

	format_mk_user_description(description, mk->mk_spec.u.identifier);
	mk_user = key_alloc(&key_type_fscrypt_user, description,
			    current_fsuid(), current_gid(), current_cred(),
			    KEY_POS_SEARCH | KEY_USR_VIEW, 0, NULL);
	if (IS_ERR(mk_user))
		return PTR_ERR(mk_user);

	err = key_instantiate_and_link(mk_user, NULL, 0, mk->mk_users, NULL);
	key_put(mk_user);
	return err;
}

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

	mk_user = find_master_key_user(mk);
	if (IS_ERR(mk_user))
		return PTR_ERR(mk_user);
	err = key_unlink(mk->mk_users, mk_user);
	key_put(mk_user);
	return err;
}

/*
 * 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(sizeof(*mk), GFP_KERNEL);
	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_decrypted_inodes);
	spin_lock_init(&mk->mk_decrypted_inodes_lock);

	if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
		err = allocate_master_key_users_keyring(mk);
		if (err)
			goto out_put;
		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;

	/*
	 * If the current user is already in ->mk_users, then there's nothing to
	 * do.  Otherwise, we need to add the user to ->mk_users.  (Neither is
	 * applicable for v1 policy keys, which have NULL ->mk_users.)
	 */
	if (mk->mk_users) {
		struct key *mk_user = find_master_key_user(mk);

		if (mk_user != ERR_PTR(-ENOKEY)) {
			if (IS_ERR(mk_user))
				return PTR_ERR(mk_user);
			key_put(mk_user);
			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;

	mutex_lock(&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);
	}
	mutex_unlock(&fscrypt_add_key_mutex);
	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) {
		err = fscrypt_init_hkdf(&secret->hkdf, secret->raw,
					secret->size);
		if (err)
			return err;

		/*
		 * Now that the HKDF context is initialized, the raw key is no
		 * longer needed.
		 */
		memzero_explicit(secret->raw, secret->size);

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

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) + FSCRYPT_MIN_KEY_SIZE ||
	    prep->datalen > sizeof(*payload) + FSCRYPT_MAX_KEY_SIZE)
		return -EINVAL;

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

	if (payload->__reserved)
		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 raw 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 field
 * fscrypt_provisioning_key_payload::type set to 'type', indicating that it's
 * only usable with fscrypt with the particular KDF version identified by
 * 'type'.  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 raw key directly instead.
 */
static int get_keyring_key(u32 key_id, u32 type,
			   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. */
	if (payload->type != type)
		goto bad_key;

	secret->size = key->datalen - sizeof(*payload);
	memcpy(secret->raw, 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.key_id) {
		if (arg.raw_size != 0)
			return -EINVAL;
		err = get_keyring_key(arg.key_id, arg.key_spec.type, &secret);
		if (err)
			goto out_wipe_secret;
	} else {
		if (arg.raw_size < FSCRYPT_MIN_KEY_SIZE ||
		    arg.raw_size > FSCRYPT_MAX_KEY_SIZE)
			return -EINVAL;
		secret.size = arg.raw_size;
		err = -EFAULT;
		if (copy_from_user(secret.raw, 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_KEY_SIZE];

	get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE);

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

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

	fscrypt_get_test_dummy_secret(&secret);

	err = fscrypt_init_hkdf(&secret.hkdf, secret.raw, secret.size);
	if (err)
		goto out;
	err = fscrypt_hkdf_expand(&secret.hkdf, HKDF_CONTEXT_KEY_IDENTIFIER,
				  NULL, 0, key_identifier,
				  FSCRYPT_KEY_IDENTIFIER_SIZE);
out:
	wipe_master_key_secret(&secret);
	return err;
}

/**
 * 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;
	struct key *mk_user;
	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);
	mk_user = find_master_key_user(mk);
	if (IS_ERR(mk_user)) {
		err = PTR_ERR(mk_user);
	} else {
		key_put(mk_user);
		err = 0;
	}
	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->i_state & (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;
	unsigned long ino;
	char ino_str[50] = "";

	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 %lu", 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 (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) {
		if (all_users)
			err = keyring_clear(mk->mk_users);
		else
			err = remove_master_key_user(mk);
		if (err) {
			up_write(&mk->mk_sem);
			goto out_put_key;
		}
		if (mk->mk_users->keys.nr_leaves_on_tree != 0) {
			/*
			 * 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;
	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;
	if (mk->mk_users) {
		struct key *mk_user;

		arg.user_count = mk->mk_users->keys.nr_leaves_on_tree;
		mk_user = find_master_key_user(mk);
		if (!IS_ERR(mk_user)) {
			arg.status_flags |=
				FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF;
			key_put(mk_user);
		} else if (mk_user != ERR_PTR(-ENOKEY)) {
			err = PTR_ERR(mk_user);
			goto out_release_key;
		}
	}
	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);

int __init fscrypt_init_keyring(void)
{
	int err;

	err = register_key_type(&key_type_fscrypt_user);
	if (err)
		return err;

	err = register_key_type(&key_type_fscrypt_provisioning);
	if (err)
		goto err_unregister_fscrypt_user;

	return 0;

err_unregister_fscrypt_user:
	unregister_key_type(&key_type_fscrypt_user);
	return err;
}
