162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Filesystem-level keyring for fscrypt 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2019 Google LLC 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * This file implements management of fscrypt master keys in the 1062306a36Sopenharmony_ci * filesystem-level keyring, including the ioctls: 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * - FS_IOC_ADD_ENCRYPTION_KEY 1362306a36Sopenharmony_ci * - FS_IOC_REMOVE_ENCRYPTION_KEY 1462306a36Sopenharmony_ci * - FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS 1562306a36Sopenharmony_ci * - FS_IOC_GET_ENCRYPTION_KEY_STATUS 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * See the "User API" section of Documentation/filesystems/fscrypt.rst for more 1862306a36Sopenharmony_ci * information about these ioctls. 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <asm/unaligned.h> 2262306a36Sopenharmony_ci#include <crypto/skcipher.h> 2362306a36Sopenharmony_ci#include <linux/key-type.h> 2462306a36Sopenharmony_ci#include <linux/random.h> 2562306a36Sopenharmony_ci#include <linux/seq_file.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include "fscrypt_private.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* The master encryption keys for a filesystem (->s_master_keys) */ 3062306a36Sopenharmony_cistruct fscrypt_keyring { 3162306a36Sopenharmony_ci /* 3262306a36Sopenharmony_ci * Lock that protects ->key_hashtable. It does *not* protect the 3362306a36Sopenharmony_ci * fscrypt_master_key structs themselves. 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci spinlock_t lock; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci /* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */ 3862306a36Sopenharmony_ci struct hlist_head key_hashtable[128]; 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic void wipe_master_key_secret(struct fscrypt_master_key_secret *secret) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci fscrypt_destroy_hkdf(&secret->hkdf); 4462306a36Sopenharmony_ci memzero_explicit(secret, sizeof(*secret)); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic void move_master_key_secret(struct fscrypt_master_key_secret *dst, 4862306a36Sopenharmony_ci struct fscrypt_master_key_secret *src) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci memcpy(dst, src, sizeof(*dst)); 5162306a36Sopenharmony_ci memzero_explicit(src, sizeof(*src)); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic void fscrypt_free_master_key(struct rcu_head *head) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci struct fscrypt_master_key *mk = 5762306a36Sopenharmony_ci container_of(head, struct fscrypt_master_key, mk_rcu_head); 5862306a36Sopenharmony_ci /* 5962306a36Sopenharmony_ci * The master key secret and any embedded subkeys should have already 6062306a36Sopenharmony_ci * been wiped when the last active reference to the fscrypt_master_key 6162306a36Sopenharmony_ci * struct was dropped; doing it here would be unnecessarily late. 6262306a36Sopenharmony_ci * Nevertheless, use kfree_sensitive() in case anything was missed. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ci kfree_sensitive(mk); 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_civoid fscrypt_put_master_key(struct fscrypt_master_key *mk) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci if (!refcount_dec_and_test(&mk->mk_struct_refs)) 7062306a36Sopenharmony_ci return; 7162306a36Sopenharmony_ci /* 7262306a36Sopenharmony_ci * No structural references left, so free ->mk_users, and also free the 7362306a36Sopenharmony_ci * fscrypt_master_key struct itself after an RCU grace period ensures 7462306a36Sopenharmony_ci * that concurrent keyring lookups can no longer find it. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_ci WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 0); 7762306a36Sopenharmony_ci key_put(mk->mk_users); 7862306a36Sopenharmony_ci mk->mk_users = NULL; 7962306a36Sopenharmony_ci call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_civoid fscrypt_put_master_key_activeref(struct super_block *sb, 8362306a36Sopenharmony_ci struct fscrypt_master_key *mk) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci size_t i; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if (!refcount_dec_and_test(&mk->mk_active_refs)) 8862306a36Sopenharmony_ci return; 8962306a36Sopenharmony_ci /* 9062306a36Sopenharmony_ci * No active references left, so complete the full removal of this 9162306a36Sopenharmony_ci * fscrypt_master_key struct by removing it from the keyring and 9262306a36Sopenharmony_ci * destroying any subkeys embedded in it. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci if (WARN_ON_ONCE(!sb->s_master_keys)) 9662306a36Sopenharmony_ci return; 9762306a36Sopenharmony_ci spin_lock(&sb->s_master_keys->lock); 9862306a36Sopenharmony_ci hlist_del_rcu(&mk->mk_node); 9962306a36Sopenharmony_ci spin_unlock(&sb->s_master_keys->lock); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci /* 10262306a36Sopenharmony_ci * ->mk_active_refs == 0 implies that ->mk_secret is not present and 10362306a36Sopenharmony_ci * that ->mk_decrypted_inodes is empty. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci WARN_ON_ONCE(is_master_key_secret_present(&mk->mk_secret)); 10662306a36Sopenharmony_ci WARN_ON_ONCE(!list_empty(&mk->mk_decrypted_inodes)); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci for (i = 0; i <= FSCRYPT_MODE_MAX; i++) { 10962306a36Sopenharmony_ci fscrypt_destroy_prepared_key( 11062306a36Sopenharmony_ci sb, &mk->mk_direct_keys[i]); 11162306a36Sopenharmony_ci fscrypt_destroy_prepared_key( 11262306a36Sopenharmony_ci sb, &mk->mk_iv_ino_lblk_64_keys[i]); 11362306a36Sopenharmony_ci fscrypt_destroy_prepared_key( 11462306a36Sopenharmony_ci sb, &mk->mk_iv_ino_lblk_32_keys[i]); 11562306a36Sopenharmony_ci } 11662306a36Sopenharmony_ci memzero_explicit(&mk->mk_ino_hash_key, 11762306a36Sopenharmony_ci sizeof(mk->mk_ino_hash_key)); 11862306a36Sopenharmony_ci mk->mk_ino_hash_key_initialized = false; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci /* Drop the structural ref associated with the active refs. */ 12162306a36Sopenharmony_ci fscrypt_put_master_key(mk); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic inline bool valid_key_spec(const struct fscrypt_key_specifier *spec) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci if (spec->__reserved) 12762306a36Sopenharmony_ci return false; 12862306a36Sopenharmony_ci return master_key_spec_len(spec) != 0; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic int fscrypt_user_key_instantiate(struct key *key, 13262306a36Sopenharmony_ci struct key_preparsed_payload *prep) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci /* 13562306a36Sopenharmony_ci * We just charge FSCRYPT_MAX_KEY_SIZE bytes to the user's key quota for 13662306a36Sopenharmony_ci * each key, regardless of the exact key size. The amount of memory 13762306a36Sopenharmony_ci * actually used is greater than the size of the raw key anyway. 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_ci return key_payload_reserve(key, FSCRYPT_MAX_KEY_SIZE); 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic void fscrypt_user_key_describe(const struct key *key, struct seq_file *m) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci seq_puts(m, key->description); 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* 14862306a36Sopenharmony_ci * Type of key in ->mk_users. Each key of this type represents a particular 14962306a36Sopenharmony_ci * user who has added a particular master key. 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * Note that the name of this key type really should be something like 15262306a36Sopenharmony_ci * ".fscrypt-user" instead of simply ".fscrypt". But the shorter name is chosen 15362306a36Sopenharmony_ci * mainly for simplicity of presentation in /proc/keys when read by a non-root 15462306a36Sopenharmony_ci * user. And it is expected to be rare that a key is actually added by multiple 15562306a36Sopenharmony_ci * users, since users should keep their encryption keys confidential. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_cistatic struct key_type key_type_fscrypt_user = { 15862306a36Sopenharmony_ci .name = ".fscrypt", 15962306a36Sopenharmony_ci .instantiate = fscrypt_user_key_instantiate, 16062306a36Sopenharmony_ci .describe = fscrypt_user_key_describe, 16162306a36Sopenharmony_ci}; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci#define FSCRYPT_MK_USERS_DESCRIPTION_SIZE \ 16462306a36Sopenharmony_ci (CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \ 16562306a36Sopenharmony_ci CONST_STRLEN("-users") + 1) 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci#define FSCRYPT_MK_USER_DESCRIPTION_SIZE \ 16862306a36Sopenharmony_ci (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1) 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic void format_mk_users_keyring_description( 17162306a36Sopenharmony_ci char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE], 17262306a36Sopenharmony_ci const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci sprintf(description, "fscrypt-%*phN-users", 17562306a36Sopenharmony_ci FSCRYPT_KEY_IDENTIFIER_SIZE, mk_identifier); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic void format_mk_user_description( 17962306a36Sopenharmony_ci char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE], 18062306a36Sopenharmony_ci const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci sprintf(description, "%*phN.uid.%u", FSCRYPT_KEY_IDENTIFIER_SIZE, 18462306a36Sopenharmony_ci mk_identifier, __kuid_val(current_fsuid())); 18562306a36Sopenharmony_ci} 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci/* Create ->s_master_keys if needed. Synchronized by fscrypt_add_key_mutex. */ 18862306a36Sopenharmony_cistatic int allocate_filesystem_keyring(struct super_block *sb) 18962306a36Sopenharmony_ci{ 19062306a36Sopenharmony_ci struct fscrypt_keyring *keyring; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci if (sb->s_master_keys) 19362306a36Sopenharmony_ci return 0; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci keyring = kzalloc(sizeof(*keyring), GFP_KERNEL); 19662306a36Sopenharmony_ci if (!keyring) 19762306a36Sopenharmony_ci return -ENOMEM; 19862306a36Sopenharmony_ci spin_lock_init(&keyring->lock); 19962306a36Sopenharmony_ci /* 20062306a36Sopenharmony_ci * Pairs with the smp_load_acquire() in fscrypt_find_master_key(). 20162306a36Sopenharmony_ci * I.e., here we publish ->s_master_keys with a RELEASE barrier so that 20262306a36Sopenharmony_ci * concurrent tasks can ACQUIRE it. 20362306a36Sopenharmony_ci */ 20462306a36Sopenharmony_ci smp_store_release(&sb->s_master_keys, keyring); 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/* 20962306a36Sopenharmony_ci * Release all encryption keys that have been added to the filesystem, along 21062306a36Sopenharmony_ci * with the keyring that contains them. 21162306a36Sopenharmony_ci * 21262306a36Sopenharmony_ci * This is called at unmount time, after all potentially-encrypted inodes have 21362306a36Sopenharmony_ci * been evicted. The filesystem's underlying block device(s) are still 21462306a36Sopenharmony_ci * available at this time; this is important because after user file accesses 21562306a36Sopenharmony_ci * have been allowed, this function may need to evict keys from the keyslots of 21662306a36Sopenharmony_ci * an inline crypto engine, which requires the block device(s). 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_civoid fscrypt_destroy_keyring(struct super_block *sb) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci struct fscrypt_keyring *keyring = sb->s_master_keys; 22162306a36Sopenharmony_ci size_t i; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci if (!keyring) 22462306a36Sopenharmony_ci return; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(keyring->key_hashtable); i++) { 22762306a36Sopenharmony_ci struct hlist_head *bucket = &keyring->key_hashtable[i]; 22862306a36Sopenharmony_ci struct fscrypt_master_key *mk; 22962306a36Sopenharmony_ci struct hlist_node *tmp; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) { 23262306a36Sopenharmony_ci /* 23362306a36Sopenharmony_ci * Since all potentially-encrypted inodes were already 23462306a36Sopenharmony_ci * evicted, every key remaining in the keyring should 23562306a36Sopenharmony_ci * have an empty inode list, and should only still be in 23662306a36Sopenharmony_ci * the keyring due to the single active ref associated 23762306a36Sopenharmony_ci * with ->mk_secret. There should be no structural refs 23862306a36Sopenharmony_ci * beyond the one associated with the active ref. 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 1); 24162306a36Sopenharmony_ci WARN_ON_ONCE(refcount_read(&mk->mk_struct_refs) != 1); 24262306a36Sopenharmony_ci WARN_ON_ONCE(!is_master_key_secret_present(&mk->mk_secret)); 24362306a36Sopenharmony_ci wipe_master_key_secret(&mk->mk_secret); 24462306a36Sopenharmony_ci fscrypt_put_master_key_activeref(sb, mk); 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci kfree_sensitive(keyring); 24862306a36Sopenharmony_ci sb->s_master_keys = NULL; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic struct hlist_head * 25262306a36Sopenharmony_cifscrypt_mk_hash_bucket(struct fscrypt_keyring *keyring, 25362306a36Sopenharmony_ci const struct fscrypt_key_specifier *mk_spec) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci /* 25662306a36Sopenharmony_ci * Since key specifiers should be "random" values, it is sufficient to 25762306a36Sopenharmony_ci * use a trivial hash function that just takes the first several bits of 25862306a36Sopenharmony_ci * the key specifier. 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci unsigned long i = get_unaligned((unsigned long *)&mk_spec->u); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci return &keyring->key_hashtable[i % ARRAY_SIZE(keyring->key_hashtable)]; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/* 26662306a36Sopenharmony_ci * Find the specified master key struct in ->s_master_keys and take a structural 26762306a36Sopenharmony_ci * ref to it. The structural ref guarantees that the key struct continues to 26862306a36Sopenharmony_ci * exist, but it does *not* guarantee that ->s_master_keys continues to contain 26962306a36Sopenharmony_ci * the key struct. The structural ref needs to be dropped by 27062306a36Sopenharmony_ci * fscrypt_put_master_key(). Returns NULL if the key struct is not found. 27162306a36Sopenharmony_ci */ 27262306a36Sopenharmony_cistruct fscrypt_master_key * 27362306a36Sopenharmony_cifscrypt_find_master_key(struct super_block *sb, 27462306a36Sopenharmony_ci const struct fscrypt_key_specifier *mk_spec) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci struct fscrypt_keyring *keyring; 27762306a36Sopenharmony_ci struct hlist_head *bucket; 27862306a36Sopenharmony_ci struct fscrypt_master_key *mk; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci /* 28162306a36Sopenharmony_ci * Pairs with the smp_store_release() in allocate_filesystem_keyring(). 28262306a36Sopenharmony_ci * I.e., another task can publish ->s_master_keys concurrently, 28362306a36Sopenharmony_ci * executing a RELEASE barrier. We need to use smp_load_acquire() here 28462306a36Sopenharmony_ci * to safely ACQUIRE the memory the other task published. 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_ci keyring = smp_load_acquire(&sb->s_master_keys); 28762306a36Sopenharmony_ci if (keyring == NULL) 28862306a36Sopenharmony_ci return NULL; /* No keyring yet, so no keys yet. */ 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci bucket = fscrypt_mk_hash_bucket(keyring, mk_spec); 29162306a36Sopenharmony_ci rcu_read_lock(); 29262306a36Sopenharmony_ci switch (mk_spec->type) { 29362306a36Sopenharmony_ci case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: 29462306a36Sopenharmony_ci hlist_for_each_entry_rcu(mk, bucket, mk_node) { 29562306a36Sopenharmony_ci if (mk->mk_spec.type == 29662306a36Sopenharmony_ci FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && 29762306a36Sopenharmony_ci memcmp(mk->mk_spec.u.descriptor, 29862306a36Sopenharmony_ci mk_spec->u.descriptor, 29962306a36Sopenharmony_ci FSCRYPT_KEY_DESCRIPTOR_SIZE) == 0 && 30062306a36Sopenharmony_ci refcount_inc_not_zero(&mk->mk_struct_refs)) 30162306a36Sopenharmony_ci goto out; 30262306a36Sopenharmony_ci } 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER: 30562306a36Sopenharmony_ci hlist_for_each_entry_rcu(mk, bucket, mk_node) { 30662306a36Sopenharmony_ci if (mk->mk_spec.type == 30762306a36Sopenharmony_ci FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER && 30862306a36Sopenharmony_ci memcmp(mk->mk_spec.u.identifier, 30962306a36Sopenharmony_ci mk_spec->u.identifier, 31062306a36Sopenharmony_ci FSCRYPT_KEY_IDENTIFIER_SIZE) == 0 && 31162306a36Sopenharmony_ci refcount_inc_not_zero(&mk->mk_struct_refs)) 31262306a36Sopenharmony_ci goto out; 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci break; 31562306a36Sopenharmony_ci } 31662306a36Sopenharmony_ci mk = NULL; 31762306a36Sopenharmony_ciout: 31862306a36Sopenharmony_ci rcu_read_unlock(); 31962306a36Sopenharmony_ci return mk; 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cistatic int allocate_master_key_users_keyring(struct fscrypt_master_key *mk) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE]; 32562306a36Sopenharmony_ci struct key *keyring; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci format_mk_users_keyring_description(description, 32862306a36Sopenharmony_ci mk->mk_spec.u.identifier); 32962306a36Sopenharmony_ci keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 33062306a36Sopenharmony_ci current_cred(), KEY_POS_SEARCH | 33162306a36Sopenharmony_ci KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW, 33262306a36Sopenharmony_ci KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 33362306a36Sopenharmony_ci if (IS_ERR(keyring)) 33462306a36Sopenharmony_ci return PTR_ERR(keyring); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci mk->mk_users = keyring; 33762306a36Sopenharmony_ci return 0; 33862306a36Sopenharmony_ci} 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci/* 34162306a36Sopenharmony_ci * Find the current user's "key" in the master key's ->mk_users. 34262306a36Sopenharmony_ci * Returns ERR_PTR(-ENOKEY) if not found. 34362306a36Sopenharmony_ci */ 34462306a36Sopenharmony_cistatic struct key *find_master_key_user(struct fscrypt_master_key *mk) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE]; 34762306a36Sopenharmony_ci key_ref_t keyref; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci format_mk_user_description(description, mk->mk_spec.u.identifier); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* 35262306a36Sopenharmony_ci * We need to mark the keyring reference as "possessed" so that we 35362306a36Sopenharmony_ci * acquire permission to search it, via the KEY_POS_SEARCH permission. 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_ci keyref = keyring_search(make_key_ref(mk->mk_users, true /*possessed*/), 35662306a36Sopenharmony_ci &key_type_fscrypt_user, description, false); 35762306a36Sopenharmony_ci if (IS_ERR(keyref)) { 35862306a36Sopenharmony_ci if (PTR_ERR(keyref) == -EAGAIN || /* not found */ 35962306a36Sopenharmony_ci PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */ 36062306a36Sopenharmony_ci keyref = ERR_PTR(-ENOKEY); 36162306a36Sopenharmony_ci return ERR_CAST(keyref); 36262306a36Sopenharmony_ci } 36362306a36Sopenharmony_ci return key_ref_to_ptr(keyref); 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci/* 36762306a36Sopenharmony_ci * Give the current user a "key" in ->mk_users. This charges the user's quota 36862306a36Sopenharmony_ci * and marks the master key as added by the current user, so that it cannot be 36962306a36Sopenharmony_ci * removed by another user with the key. Either ->mk_sem must be held for 37062306a36Sopenharmony_ci * write, or the master key must be still undergoing initialization. 37162306a36Sopenharmony_ci */ 37262306a36Sopenharmony_cistatic int add_master_key_user(struct fscrypt_master_key *mk) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE]; 37562306a36Sopenharmony_ci struct key *mk_user; 37662306a36Sopenharmony_ci int err; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci format_mk_user_description(description, mk->mk_spec.u.identifier); 37962306a36Sopenharmony_ci mk_user = key_alloc(&key_type_fscrypt_user, description, 38062306a36Sopenharmony_ci current_fsuid(), current_gid(), current_cred(), 38162306a36Sopenharmony_ci KEY_POS_SEARCH | KEY_USR_VIEW, 0, NULL); 38262306a36Sopenharmony_ci if (IS_ERR(mk_user)) 38362306a36Sopenharmony_ci return PTR_ERR(mk_user); 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci err = key_instantiate_and_link(mk_user, NULL, 0, mk->mk_users, NULL); 38662306a36Sopenharmony_ci key_put(mk_user); 38762306a36Sopenharmony_ci return err; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci/* 39162306a36Sopenharmony_ci * Remove the current user's "key" from ->mk_users. 39262306a36Sopenharmony_ci * ->mk_sem must be held for write. 39362306a36Sopenharmony_ci * 39462306a36Sopenharmony_ci * Returns 0 if removed, -ENOKEY if not found, or another -errno code. 39562306a36Sopenharmony_ci */ 39662306a36Sopenharmony_cistatic int remove_master_key_user(struct fscrypt_master_key *mk) 39762306a36Sopenharmony_ci{ 39862306a36Sopenharmony_ci struct key *mk_user; 39962306a36Sopenharmony_ci int err; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci mk_user = find_master_key_user(mk); 40262306a36Sopenharmony_ci if (IS_ERR(mk_user)) 40362306a36Sopenharmony_ci return PTR_ERR(mk_user); 40462306a36Sopenharmony_ci err = key_unlink(mk->mk_users, mk_user); 40562306a36Sopenharmony_ci key_put(mk_user); 40662306a36Sopenharmony_ci return err; 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci/* 41062306a36Sopenharmony_ci * Allocate a new fscrypt_master_key, transfer the given secret over to it, and 41162306a36Sopenharmony_ci * insert it into sb->s_master_keys. 41262306a36Sopenharmony_ci */ 41362306a36Sopenharmony_cistatic int add_new_master_key(struct super_block *sb, 41462306a36Sopenharmony_ci struct fscrypt_master_key_secret *secret, 41562306a36Sopenharmony_ci const struct fscrypt_key_specifier *mk_spec) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci struct fscrypt_keyring *keyring = sb->s_master_keys; 41862306a36Sopenharmony_ci struct fscrypt_master_key *mk; 41962306a36Sopenharmony_ci int err; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci mk = kzalloc(sizeof(*mk), GFP_KERNEL); 42262306a36Sopenharmony_ci if (!mk) 42362306a36Sopenharmony_ci return -ENOMEM; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci init_rwsem(&mk->mk_sem); 42662306a36Sopenharmony_ci refcount_set(&mk->mk_struct_refs, 1); 42762306a36Sopenharmony_ci mk->mk_spec = *mk_spec; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci INIT_LIST_HEAD(&mk->mk_decrypted_inodes); 43062306a36Sopenharmony_ci spin_lock_init(&mk->mk_decrypted_inodes_lock); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { 43362306a36Sopenharmony_ci err = allocate_master_key_users_keyring(mk); 43462306a36Sopenharmony_ci if (err) 43562306a36Sopenharmony_ci goto out_put; 43662306a36Sopenharmony_ci err = add_master_key_user(mk); 43762306a36Sopenharmony_ci if (err) 43862306a36Sopenharmony_ci goto out_put; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci move_master_key_secret(&mk->mk_secret, secret); 44262306a36Sopenharmony_ci refcount_set(&mk->mk_active_refs, 1); /* ->mk_secret is present */ 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci spin_lock(&keyring->lock); 44562306a36Sopenharmony_ci hlist_add_head_rcu(&mk->mk_node, 44662306a36Sopenharmony_ci fscrypt_mk_hash_bucket(keyring, mk_spec)); 44762306a36Sopenharmony_ci spin_unlock(&keyring->lock); 44862306a36Sopenharmony_ci return 0; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ciout_put: 45162306a36Sopenharmony_ci fscrypt_put_master_key(mk); 45262306a36Sopenharmony_ci return err; 45362306a36Sopenharmony_ci} 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci#define KEY_DEAD 1 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistatic int add_existing_master_key(struct fscrypt_master_key *mk, 45862306a36Sopenharmony_ci struct fscrypt_master_key_secret *secret) 45962306a36Sopenharmony_ci{ 46062306a36Sopenharmony_ci int err; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci /* 46362306a36Sopenharmony_ci * If the current user is already in ->mk_users, then there's nothing to 46462306a36Sopenharmony_ci * do. Otherwise, we need to add the user to ->mk_users. (Neither is 46562306a36Sopenharmony_ci * applicable for v1 policy keys, which have NULL ->mk_users.) 46662306a36Sopenharmony_ci */ 46762306a36Sopenharmony_ci if (mk->mk_users) { 46862306a36Sopenharmony_ci struct key *mk_user = find_master_key_user(mk); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci if (mk_user != ERR_PTR(-ENOKEY)) { 47162306a36Sopenharmony_ci if (IS_ERR(mk_user)) 47262306a36Sopenharmony_ci return PTR_ERR(mk_user); 47362306a36Sopenharmony_ci key_put(mk_user); 47462306a36Sopenharmony_ci return 0; 47562306a36Sopenharmony_ci } 47662306a36Sopenharmony_ci err = add_master_key_user(mk); 47762306a36Sopenharmony_ci if (err) 47862306a36Sopenharmony_ci return err; 47962306a36Sopenharmony_ci } 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci /* Re-add the secret if needed. */ 48262306a36Sopenharmony_ci if (!is_master_key_secret_present(&mk->mk_secret)) { 48362306a36Sopenharmony_ci if (!refcount_inc_not_zero(&mk->mk_active_refs)) 48462306a36Sopenharmony_ci return KEY_DEAD; 48562306a36Sopenharmony_ci move_master_key_secret(&mk->mk_secret, secret); 48662306a36Sopenharmony_ci } 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci return 0; 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic int do_add_master_key(struct super_block *sb, 49262306a36Sopenharmony_ci struct fscrypt_master_key_secret *secret, 49362306a36Sopenharmony_ci const struct fscrypt_key_specifier *mk_spec) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci static DEFINE_MUTEX(fscrypt_add_key_mutex); 49662306a36Sopenharmony_ci struct fscrypt_master_key *mk; 49762306a36Sopenharmony_ci int err; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci mutex_lock(&fscrypt_add_key_mutex); /* serialize find + link */ 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci mk = fscrypt_find_master_key(sb, mk_spec); 50262306a36Sopenharmony_ci if (!mk) { 50362306a36Sopenharmony_ci /* Didn't find the key in ->s_master_keys. Add it. */ 50462306a36Sopenharmony_ci err = allocate_filesystem_keyring(sb); 50562306a36Sopenharmony_ci if (!err) 50662306a36Sopenharmony_ci err = add_new_master_key(sb, secret, mk_spec); 50762306a36Sopenharmony_ci } else { 50862306a36Sopenharmony_ci /* 50962306a36Sopenharmony_ci * Found the key in ->s_master_keys. Re-add the secret if 51062306a36Sopenharmony_ci * needed, and add the user to ->mk_users if needed. 51162306a36Sopenharmony_ci */ 51262306a36Sopenharmony_ci down_write(&mk->mk_sem); 51362306a36Sopenharmony_ci err = add_existing_master_key(mk, secret); 51462306a36Sopenharmony_ci up_write(&mk->mk_sem); 51562306a36Sopenharmony_ci if (err == KEY_DEAD) { 51662306a36Sopenharmony_ci /* 51762306a36Sopenharmony_ci * We found a key struct, but it's already been fully 51862306a36Sopenharmony_ci * removed. Ignore the old struct and add a new one. 51962306a36Sopenharmony_ci * fscrypt_add_key_mutex means we don't need to worry 52062306a36Sopenharmony_ci * about concurrent adds. 52162306a36Sopenharmony_ci */ 52262306a36Sopenharmony_ci err = add_new_master_key(sb, secret, mk_spec); 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci fscrypt_put_master_key(mk); 52562306a36Sopenharmony_ci } 52662306a36Sopenharmony_ci mutex_unlock(&fscrypt_add_key_mutex); 52762306a36Sopenharmony_ci return err; 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_cistatic int add_master_key(struct super_block *sb, 53162306a36Sopenharmony_ci struct fscrypt_master_key_secret *secret, 53262306a36Sopenharmony_ci struct fscrypt_key_specifier *key_spec) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci int err; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci if (key_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { 53762306a36Sopenharmony_ci err = fscrypt_init_hkdf(&secret->hkdf, secret->raw, 53862306a36Sopenharmony_ci secret->size); 53962306a36Sopenharmony_ci if (err) 54062306a36Sopenharmony_ci return err; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci /* 54362306a36Sopenharmony_ci * Now that the HKDF context is initialized, the raw key is no 54462306a36Sopenharmony_ci * longer needed. 54562306a36Sopenharmony_ci */ 54662306a36Sopenharmony_ci memzero_explicit(secret->raw, secret->size); 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci /* Calculate the key identifier */ 54962306a36Sopenharmony_ci err = fscrypt_hkdf_expand(&secret->hkdf, 55062306a36Sopenharmony_ci HKDF_CONTEXT_KEY_IDENTIFIER, NULL, 0, 55162306a36Sopenharmony_ci key_spec->u.identifier, 55262306a36Sopenharmony_ci FSCRYPT_KEY_IDENTIFIER_SIZE); 55362306a36Sopenharmony_ci if (err) 55462306a36Sopenharmony_ci return err; 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci return do_add_master_key(sb, secret, key_spec); 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistatic int fscrypt_provisioning_key_preparse(struct key_preparsed_payload *prep) 56062306a36Sopenharmony_ci{ 56162306a36Sopenharmony_ci const struct fscrypt_provisioning_key_payload *payload = prep->data; 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci if (prep->datalen < sizeof(*payload) + FSCRYPT_MIN_KEY_SIZE || 56462306a36Sopenharmony_ci prep->datalen > sizeof(*payload) + FSCRYPT_MAX_KEY_SIZE) 56562306a36Sopenharmony_ci return -EINVAL; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci if (payload->type != FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && 56862306a36Sopenharmony_ci payload->type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) 56962306a36Sopenharmony_ci return -EINVAL; 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci if (payload->__reserved) 57262306a36Sopenharmony_ci return -EINVAL; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci prep->payload.data[0] = kmemdup(payload, prep->datalen, GFP_KERNEL); 57562306a36Sopenharmony_ci if (!prep->payload.data[0]) 57662306a36Sopenharmony_ci return -ENOMEM; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci prep->quotalen = prep->datalen; 57962306a36Sopenharmony_ci return 0; 58062306a36Sopenharmony_ci} 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_cistatic void fscrypt_provisioning_key_free_preparse( 58362306a36Sopenharmony_ci struct key_preparsed_payload *prep) 58462306a36Sopenharmony_ci{ 58562306a36Sopenharmony_ci kfree_sensitive(prep->payload.data[0]); 58662306a36Sopenharmony_ci} 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistatic void fscrypt_provisioning_key_describe(const struct key *key, 58962306a36Sopenharmony_ci struct seq_file *m) 59062306a36Sopenharmony_ci{ 59162306a36Sopenharmony_ci seq_puts(m, key->description); 59262306a36Sopenharmony_ci if (key_is_positive(key)) { 59362306a36Sopenharmony_ci const struct fscrypt_provisioning_key_payload *payload = 59462306a36Sopenharmony_ci key->payload.data[0]; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci seq_printf(m, ": %u [%u]", key->datalen, payload->type); 59762306a36Sopenharmony_ci } 59862306a36Sopenharmony_ci} 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistatic void fscrypt_provisioning_key_destroy(struct key *key) 60162306a36Sopenharmony_ci{ 60262306a36Sopenharmony_ci kfree_sensitive(key->payload.data[0]); 60362306a36Sopenharmony_ci} 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_cistatic struct key_type key_type_fscrypt_provisioning = { 60662306a36Sopenharmony_ci .name = "fscrypt-provisioning", 60762306a36Sopenharmony_ci .preparse = fscrypt_provisioning_key_preparse, 60862306a36Sopenharmony_ci .free_preparse = fscrypt_provisioning_key_free_preparse, 60962306a36Sopenharmony_ci .instantiate = generic_key_instantiate, 61062306a36Sopenharmony_ci .describe = fscrypt_provisioning_key_describe, 61162306a36Sopenharmony_ci .destroy = fscrypt_provisioning_key_destroy, 61262306a36Sopenharmony_ci}; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci/* 61562306a36Sopenharmony_ci * Retrieve the raw key from the Linux keyring key specified by 'key_id', and 61662306a36Sopenharmony_ci * store it into 'secret'. 61762306a36Sopenharmony_ci * 61862306a36Sopenharmony_ci * The key must be of type "fscrypt-provisioning" and must have the field 61962306a36Sopenharmony_ci * fscrypt_provisioning_key_payload::type set to 'type', indicating that it's 62062306a36Sopenharmony_ci * only usable with fscrypt with the particular KDF version identified by 62162306a36Sopenharmony_ci * 'type'. We don't use the "logon" key type because there's no way to 62262306a36Sopenharmony_ci * completely restrict the use of such keys; they can be used by any kernel API 62362306a36Sopenharmony_ci * that accepts "logon" keys and doesn't require a specific service prefix. 62462306a36Sopenharmony_ci * 62562306a36Sopenharmony_ci * The ability to specify the key via Linux keyring key is intended for cases 62662306a36Sopenharmony_ci * where userspace needs to re-add keys after the filesystem is unmounted and 62762306a36Sopenharmony_ci * re-mounted. Most users should just provide the raw key directly instead. 62862306a36Sopenharmony_ci */ 62962306a36Sopenharmony_cistatic int get_keyring_key(u32 key_id, u32 type, 63062306a36Sopenharmony_ci struct fscrypt_master_key_secret *secret) 63162306a36Sopenharmony_ci{ 63262306a36Sopenharmony_ci key_ref_t ref; 63362306a36Sopenharmony_ci struct key *key; 63462306a36Sopenharmony_ci const struct fscrypt_provisioning_key_payload *payload; 63562306a36Sopenharmony_ci int err; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci ref = lookup_user_key(key_id, 0, KEY_NEED_SEARCH); 63862306a36Sopenharmony_ci if (IS_ERR(ref)) 63962306a36Sopenharmony_ci return PTR_ERR(ref); 64062306a36Sopenharmony_ci key = key_ref_to_ptr(ref); 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci if (key->type != &key_type_fscrypt_provisioning) 64362306a36Sopenharmony_ci goto bad_key; 64462306a36Sopenharmony_ci payload = key->payload.data[0]; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */ 64762306a36Sopenharmony_ci if (payload->type != type) 64862306a36Sopenharmony_ci goto bad_key; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci secret->size = key->datalen - sizeof(*payload); 65162306a36Sopenharmony_ci memcpy(secret->raw, payload->raw, secret->size); 65262306a36Sopenharmony_ci err = 0; 65362306a36Sopenharmony_ci goto out_put; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_cibad_key: 65662306a36Sopenharmony_ci err = -EKEYREJECTED; 65762306a36Sopenharmony_ciout_put: 65862306a36Sopenharmony_ci key_ref_put(ref); 65962306a36Sopenharmony_ci return err; 66062306a36Sopenharmony_ci} 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci/* 66362306a36Sopenharmony_ci * Add a master encryption key to the filesystem, causing all files which were 66462306a36Sopenharmony_ci * encrypted with it to appear "unlocked" (decrypted) when accessed. 66562306a36Sopenharmony_ci * 66662306a36Sopenharmony_ci * When adding a key for use by v1 encryption policies, this ioctl is 66762306a36Sopenharmony_ci * privileged, and userspace must provide the 'key_descriptor'. 66862306a36Sopenharmony_ci * 66962306a36Sopenharmony_ci * When adding a key for use by v2+ encryption policies, this ioctl is 67062306a36Sopenharmony_ci * unprivileged. This is needed, in general, to allow non-root users to use 67162306a36Sopenharmony_ci * encryption without encountering the visibility problems of process-subscribed 67262306a36Sopenharmony_ci * keyrings and the inability to properly remove keys. This works by having 67362306a36Sopenharmony_ci * each key identified by its cryptographically secure hash --- the 67462306a36Sopenharmony_ci * 'key_identifier'. The cryptographic hash ensures that a malicious user 67562306a36Sopenharmony_ci * cannot add the wrong key for a given identifier. Furthermore, each added key 67662306a36Sopenharmony_ci * is charged to the appropriate user's quota for the keyrings service, which 67762306a36Sopenharmony_ci * prevents a malicious user from adding too many keys. Finally, we forbid a 67862306a36Sopenharmony_ci * user from removing a key while other users have added it too, which prevents 67962306a36Sopenharmony_ci * a user who knows another user's key from causing a denial-of-service by 68062306a36Sopenharmony_ci * removing it at an inopportune time. (We tolerate that a user who knows a key 68162306a36Sopenharmony_ci * can prevent other users from removing it.) 68262306a36Sopenharmony_ci * 68362306a36Sopenharmony_ci * For more details, see the "FS_IOC_ADD_ENCRYPTION_KEY" section of 68462306a36Sopenharmony_ci * Documentation/filesystems/fscrypt.rst. 68562306a36Sopenharmony_ci */ 68662306a36Sopenharmony_ciint fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg) 68762306a36Sopenharmony_ci{ 68862306a36Sopenharmony_ci struct super_block *sb = file_inode(filp)->i_sb; 68962306a36Sopenharmony_ci struct fscrypt_add_key_arg __user *uarg = _uarg; 69062306a36Sopenharmony_ci struct fscrypt_add_key_arg arg; 69162306a36Sopenharmony_ci struct fscrypt_master_key_secret secret; 69262306a36Sopenharmony_ci int err; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci if (copy_from_user(&arg, uarg, sizeof(arg))) 69562306a36Sopenharmony_ci return -EFAULT; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci if (!valid_key_spec(&arg.key_spec)) 69862306a36Sopenharmony_ci return -EINVAL; 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved))) 70162306a36Sopenharmony_ci return -EINVAL; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci /* 70462306a36Sopenharmony_ci * Only root can add keys that are identified by an arbitrary descriptor 70562306a36Sopenharmony_ci * rather than by a cryptographic hash --- since otherwise a malicious 70662306a36Sopenharmony_ci * user could add the wrong key. 70762306a36Sopenharmony_ci */ 70862306a36Sopenharmony_ci if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && 70962306a36Sopenharmony_ci !capable(CAP_SYS_ADMIN)) 71062306a36Sopenharmony_ci return -EACCES; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci memset(&secret, 0, sizeof(secret)); 71362306a36Sopenharmony_ci if (arg.key_id) { 71462306a36Sopenharmony_ci if (arg.raw_size != 0) 71562306a36Sopenharmony_ci return -EINVAL; 71662306a36Sopenharmony_ci err = get_keyring_key(arg.key_id, arg.key_spec.type, &secret); 71762306a36Sopenharmony_ci if (err) 71862306a36Sopenharmony_ci goto out_wipe_secret; 71962306a36Sopenharmony_ci } else { 72062306a36Sopenharmony_ci if (arg.raw_size < FSCRYPT_MIN_KEY_SIZE || 72162306a36Sopenharmony_ci arg.raw_size > FSCRYPT_MAX_KEY_SIZE) 72262306a36Sopenharmony_ci return -EINVAL; 72362306a36Sopenharmony_ci secret.size = arg.raw_size; 72462306a36Sopenharmony_ci err = -EFAULT; 72562306a36Sopenharmony_ci if (copy_from_user(secret.raw, uarg->raw, secret.size)) 72662306a36Sopenharmony_ci goto out_wipe_secret; 72762306a36Sopenharmony_ci } 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci err = add_master_key(sb, &secret, &arg.key_spec); 73062306a36Sopenharmony_ci if (err) 73162306a36Sopenharmony_ci goto out_wipe_secret; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci /* Return the key identifier to userspace, if applicable */ 73462306a36Sopenharmony_ci err = -EFAULT; 73562306a36Sopenharmony_ci if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER && 73662306a36Sopenharmony_ci copy_to_user(uarg->key_spec.u.identifier, arg.key_spec.u.identifier, 73762306a36Sopenharmony_ci FSCRYPT_KEY_IDENTIFIER_SIZE)) 73862306a36Sopenharmony_ci goto out_wipe_secret; 73962306a36Sopenharmony_ci err = 0; 74062306a36Sopenharmony_ciout_wipe_secret: 74162306a36Sopenharmony_ci wipe_master_key_secret(&secret); 74262306a36Sopenharmony_ci return err; 74362306a36Sopenharmony_ci} 74462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_ioctl_add_key); 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_cistatic void 74762306a36Sopenharmony_cifscrypt_get_test_dummy_secret(struct fscrypt_master_key_secret *secret) 74862306a36Sopenharmony_ci{ 74962306a36Sopenharmony_ci static u8 test_key[FSCRYPT_MAX_KEY_SIZE]; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE); 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci memset(secret, 0, sizeof(*secret)); 75462306a36Sopenharmony_ci secret->size = FSCRYPT_MAX_KEY_SIZE; 75562306a36Sopenharmony_ci memcpy(secret->raw, test_key, FSCRYPT_MAX_KEY_SIZE); 75662306a36Sopenharmony_ci} 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ciint fscrypt_get_test_dummy_key_identifier( 75962306a36Sopenharmony_ci u8 key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci struct fscrypt_master_key_secret secret; 76262306a36Sopenharmony_ci int err; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci fscrypt_get_test_dummy_secret(&secret); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci err = fscrypt_init_hkdf(&secret.hkdf, secret.raw, secret.size); 76762306a36Sopenharmony_ci if (err) 76862306a36Sopenharmony_ci goto out; 76962306a36Sopenharmony_ci err = fscrypt_hkdf_expand(&secret.hkdf, HKDF_CONTEXT_KEY_IDENTIFIER, 77062306a36Sopenharmony_ci NULL, 0, key_identifier, 77162306a36Sopenharmony_ci FSCRYPT_KEY_IDENTIFIER_SIZE); 77262306a36Sopenharmony_ciout: 77362306a36Sopenharmony_ci wipe_master_key_secret(&secret); 77462306a36Sopenharmony_ci return err; 77562306a36Sopenharmony_ci} 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci/** 77862306a36Sopenharmony_ci * fscrypt_add_test_dummy_key() - add the test dummy encryption key 77962306a36Sopenharmony_ci * @sb: the filesystem instance to add the key to 78062306a36Sopenharmony_ci * @key_spec: the key specifier of the test dummy encryption key 78162306a36Sopenharmony_ci * 78262306a36Sopenharmony_ci * Add the key for the test_dummy_encryption mount option to the filesystem. To 78362306a36Sopenharmony_ci * prevent misuse of this mount option, a per-boot random key is used instead of 78462306a36Sopenharmony_ci * a hardcoded one. This makes it so that any encrypted files created using 78562306a36Sopenharmony_ci * this option won't be accessible after a reboot. 78662306a36Sopenharmony_ci * 78762306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 78862306a36Sopenharmony_ci */ 78962306a36Sopenharmony_ciint fscrypt_add_test_dummy_key(struct super_block *sb, 79062306a36Sopenharmony_ci struct fscrypt_key_specifier *key_spec) 79162306a36Sopenharmony_ci{ 79262306a36Sopenharmony_ci struct fscrypt_master_key_secret secret; 79362306a36Sopenharmony_ci int err; 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci fscrypt_get_test_dummy_secret(&secret); 79662306a36Sopenharmony_ci err = add_master_key(sb, &secret, key_spec); 79762306a36Sopenharmony_ci wipe_master_key_secret(&secret); 79862306a36Sopenharmony_ci return err; 79962306a36Sopenharmony_ci} 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci/* 80262306a36Sopenharmony_ci * Verify that the current user has added a master key with the given identifier 80362306a36Sopenharmony_ci * (returns -ENOKEY if not). This is needed to prevent a user from encrypting 80462306a36Sopenharmony_ci * their files using some other user's key which they don't actually know. 80562306a36Sopenharmony_ci * Cryptographically this isn't much of a problem, but the semantics of this 80662306a36Sopenharmony_ci * would be a bit weird, so it's best to just forbid it. 80762306a36Sopenharmony_ci * 80862306a36Sopenharmony_ci * The system administrator (CAP_FOWNER) can override this, which should be 80962306a36Sopenharmony_ci * enough for any use cases where encryption policies are being set using keys 81062306a36Sopenharmony_ci * that were chosen ahead of time but aren't available at the moment. 81162306a36Sopenharmony_ci * 81262306a36Sopenharmony_ci * Note that the key may have already removed by the time this returns, but 81362306a36Sopenharmony_ci * that's okay; we just care whether the key was there at some point. 81462306a36Sopenharmony_ci * 81562306a36Sopenharmony_ci * Return: 0 if the key is added, -ENOKEY if it isn't, or another -errno code 81662306a36Sopenharmony_ci */ 81762306a36Sopenharmony_ciint fscrypt_verify_key_added(struct super_block *sb, 81862306a36Sopenharmony_ci const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci struct fscrypt_key_specifier mk_spec; 82162306a36Sopenharmony_ci struct fscrypt_master_key *mk; 82262306a36Sopenharmony_ci struct key *mk_user; 82362306a36Sopenharmony_ci int err; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; 82662306a36Sopenharmony_ci memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE); 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci mk = fscrypt_find_master_key(sb, &mk_spec); 82962306a36Sopenharmony_ci if (!mk) { 83062306a36Sopenharmony_ci err = -ENOKEY; 83162306a36Sopenharmony_ci goto out; 83262306a36Sopenharmony_ci } 83362306a36Sopenharmony_ci down_read(&mk->mk_sem); 83462306a36Sopenharmony_ci mk_user = find_master_key_user(mk); 83562306a36Sopenharmony_ci if (IS_ERR(mk_user)) { 83662306a36Sopenharmony_ci err = PTR_ERR(mk_user); 83762306a36Sopenharmony_ci } else { 83862306a36Sopenharmony_ci key_put(mk_user); 83962306a36Sopenharmony_ci err = 0; 84062306a36Sopenharmony_ci } 84162306a36Sopenharmony_ci up_read(&mk->mk_sem); 84262306a36Sopenharmony_ci fscrypt_put_master_key(mk); 84362306a36Sopenharmony_ciout: 84462306a36Sopenharmony_ci if (err == -ENOKEY && capable(CAP_FOWNER)) 84562306a36Sopenharmony_ci err = 0; 84662306a36Sopenharmony_ci return err; 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci/* 85062306a36Sopenharmony_ci * Try to evict the inode's dentries from the dentry cache. If the inode is a 85162306a36Sopenharmony_ci * directory, then it can have at most one dentry; however, that dentry may be 85262306a36Sopenharmony_ci * pinned by child dentries, so first try to evict the children too. 85362306a36Sopenharmony_ci */ 85462306a36Sopenharmony_cistatic void shrink_dcache_inode(struct inode *inode) 85562306a36Sopenharmony_ci{ 85662306a36Sopenharmony_ci struct dentry *dentry; 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode)) { 85962306a36Sopenharmony_ci dentry = d_find_any_alias(inode); 86062306a36Sopenharmony_ci if (dentry) { 86162306a36Sopenharmony_ci shrink_dcache_parent(dentry); 86262306a36Sopenharmony_ci dput(dentry); 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci } 86562306a36Sopenharmony_ci d_prune_aliases(inode); 86662306a36Sopenharmony_ci} 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_cistatic void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk) 86962306a36Sopenharmony_ci{ 87062306a36Sopenharmony_ci struct fscrypt_info *ci; 87162306a36Sopenharmony_ci struct inode *inode; 87262306a36Sopenharmony_ci struct inode *toput_inode = NULL; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci spin_lock(&mk->mk_decrypted_inodes_lock); 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci list_for_each_entry(ci, &mk->mk_decrypted_inodes, ci_master_key_link) { 87762306a36Sopenharmony_ci inode = ci->ci_inode; 87862306a36Sopenharmony_ci spin_lock(&inode->i_lock); 87962306a36Sopenharmony_ci if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) { 88062306a36Sopenharmony_ci spin_unlock(&inode->i_lock); 88162306a36Sopenharmony_ci continue; 88262306a36Sopenharmony_ci } 88362306a36Sopenharmony_ci __iget(inode); 88462306a36Sopenharmony_ci spin_unlock(&inode->i_lock); 88562306a36Sopenharmony_ci spin_unlock(&mk->mk_decrypted_inodes_lock); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci shrink_dcache_inode(inode); 88862306a36Sopenharmony_ci iput(toput_inode); 88962306a36Sopenharmony_ci toput_inode = inode; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci spin_lock(&mk->mk_decrypted_inodes_lock); 89262306a36Sopenharmony_ci } 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci spin_unlock(&mk->mk_decrypted_inodes_lock); 89562306a36Sopenharmony_ci iput(toput_inode); 89662306a36Sopenharmony_ci} 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_cistatic int check_for_busy_inodes(struct super_block *sb, 89962306a36Sopenharmony_ci struct fscrypt_master_key *mk) 90062306a36Sopenharmony_ci{ 90162306a36Sopenharmony_ci struct list_head *pos; 90262306a36Sopenharmony_ci size_t busy_count = 0; 90362306a36Sopenharmony_ci unsigned long ino; 90462306a36Sopenharmony_ci char ino_str[50] = ""; 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci spin_lock(&mk->mk_decrypted_inodes_lock); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci list_for_each(pos, &mk->mk_decrypted_inodes) 90962306a36Sopenharmony_ci busy_count++; 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci if (busy_count == 0) { 91262306a36Sopenharmony_ci spin_unlock(&mk->mk_decrypted_inodes_lock); 91362306a36Sopenharmony_ci return 0; 91462306a36Sopenharmony_ci } 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci { 91762306a36Sopenharmony_ci /* select an example file to show for debugging purposes */ 91862306a36Sopenharmony_ci struct inode *inode = 91962306a36Sopenharmony_ci list_first_entry(&mk->mk_decrypted_inodes, 92062306a36Sopenharmony_ci struct fscrypt_info, 92162306a36Sopenharmony_ci ci_master_key_link)->ci_inode; 92262306a36Sopenharmony_ci ino = inode->i_ino; 92362306a36Sopenharmony_ci } 92462306a36Sopenharmony_ci spin_unlock(&mk->mk_decrypted_inodes_lock); 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci /* If the inode is currently being created, ino may still be 0. */ 92762306a36Sopenharmony_ci if (ino) 92862306a36Sopenharmony_ci snprintf(ino_str, sizeof(ino_str), ", including ino %lu", ino); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci fscrypt_warn(NULL, 93162306a36Sopenharmony_ci "%s: %zu inode(s) still busy after removing key with %s %*phN%s", 93262306a36Sopenharmony_ci sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec), 93362306a36Sopenharmony_ci master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u, 93462306a36Sopenharmony_ci ino_str); 93562306a36Sopenharmony_ci return -EBUSY; 93662306a36Sopenharmony_ci} 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_cistatic int try_to_lock_encrypted_files(struct super_block *sb, 93962306a36Sopenharmony_ci struct fscrypt_master_key *mk) 94062306a36Sopenharmony_ci{ 94162306a36Sopenharmony_ci int err1; 94262306a36Sopenharmony_ci int err2; 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci /* 94562306a36Sopenharmony_ci * An inode can't be evicted while it is dirty or has dirty pages. 94662306a36Sopenharmony_ci * Thus, we first have to clean the inodes in ->mk_decrypted_inodes. 94762306a36Sopenharmony_ci * 94862306a36Sopenharmony_ci * Just do it the easy way: call sync_filesystem(). It's overkill, but 94962306a36Sopenharmony_ci * it works, and it's more important to minimize the amount of caches we 95062306a36Sopenharmony_ci * drop than the amount of data we sync. Also, unprivileged users can 95162306a36Sopenharmony_ci * already call sync_filesystem() via sys_syncfs() or sys_sync(). 95262306a36Sopenharmony_ci */ 95362306a36Sopenharmony_ci down_read(&sb->s_umount); 95462306a36Sopenharmony_ci err1 = sync_filesystem(sb); 95562306a36Sopenharmony_ci up_read(&sb->s_umount); 95662306a36Sopenharmony_ci /* If a sync error occurs, still try to evict as much as possible. */ 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci /* 95962306a36Sopenharmony_ci * Inodes are pinned by their dentries, so we have to evict their 96062306a36Sopenharmony_ci * dentries. shrink_dcache_sb() would suffice, but would be overkill 96162306a36Sopenharmony_ci * and inappropriate for use by unprivileged users. So instead go 96262306a36Sopenharmony_ci * through the inodes' alias lists and try to evict each dentry. 96362306a36Sopenharmony_ci */ 96462306a36Sopenharmony_ci evict_dentries_for_decrypted_inodes(mk); 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci /* 96762306a36Sopenharmony_ci * evict_dentries_for_decrypted_inodes() already iput() each inode in 96862306a36Sopenharmony_ci * the list; any inodes for which that dropped the last reference will 96962306a36Sopenharmony_ci * have been evicted due to fscrypt_drop_inode() detecting the key 97062306a36Sopenharmony_ci * removal and telling the VFS to evict the inode. So to finish, we 97162306a36Sopenharmony_ci * just need to check whether any inodes couldn't be evicted. 97262306a36Sopenharmony_ci */ 97362306a36Sopenharmony_ci err2 = check_for_busy_inodes(sb, mk); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci return err1 ?: err2; 97662306a36Sopenharmony_ci} 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci/* 97962306a36Sopenharmony_ci * Try to remove an fscrypt master encryption key. 98062306a36Sopenharmony_ci * 98162306a36Sopenharmony_ci * FS_IOC_REMOVE_ENCRYPTION_KEY (all_users=false) removes the current user's 98262306a36Sopenharmony_ci * claim to the key, then removes the key itself if no other users have claims. 98362306a36Sopenharmony_ci * FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS (all_users=true) always removes the 98462306a36Sopenharmony_ci * key itself. 98562306a36Sopenharmony_ci * 98662306a36Sopenharmony_ci * To "remove the key itself", first we wipe the actual master key secret, so 98762306a36Sopenharmony_ci * that no more inodes can be unlocked with it. Then we try to evict all cached 98862306a36Sopenharmony_ci * inodes that had been unlocked with the key. 98962306a36Sopenharmony_ci * 99062306a36Sopenharmony_ci * If all inodes were evicted, then we unlink the fscrypt_master_key from the 99162306a36Sopenharmony_ci * keyring. Otherwise it remains in the keyring in the "incompletely removed" 99262306a36Sopenharmony_ci * state (without the actual secret key) where it tracks the list of remaining 99362306a36Sopenharmony_ci * inodes. Userspace can execute the ioctl again later to retry eviction, or 99462306a36Sopenharmony_ci * alternatively can re-add the secret key again. 99562306a36Sopenharmony_ci * 99662306a36Sopenharmony_ci * For more details, see the "Removing keys" section of 99762306a36Sopenharmony_ci * Documentation/filesystems/fscrypt.rst. 99862306a36Sopenharmony_ci */ 99962306a36Sopenharmony_cistatic int do_remove_key(struct file *filp, void __user *_uarg, bool all_users) 100062306a36Sopenharmony_ci{ 100162306a36Sopenharmony_ci struct super_block *sb = file_inode(filp)->i_sb; 100262306a36Sopenharmony_ci struct fscrypt_remove_key_arg __user *uarg = _uarg; 100362306a36Sopenharmony_ci struct fscrypt_remove_key_arg arg; 100462306a36Sopenharmony_ci struct fscrypt_master_key *mk; 100562306a36Sopenharmony_ci u32 status_flags = 0; 100662306a36Sopenharmony_ci int err; 100762306a36Sopenharmony_ci bool inodes_remain; 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci if (copy_from_user(&arg, uarg, sizeof(arg))) 101062306a36Sopenharmony_ci return -EFAULT; 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci if (!valid_key_spec(&arg.key_spec)) 101362306a36Sopenharmony_ci return -EINVAL; 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved))) 101662306a36Sopenharmony_ci return -EINVAL; 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci /* 101962306a36Sopenharmony_ci * Only root can add and remove keys that are identified by an arbitrary 102062306a36Sopenharmony_ci * descriptor rather than by a cryptographic hash. 102162306a36Sopenharmony_ci */ 102262306a36Sopenharmony_ci if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && 102362306a36Sopenharmony_ci !capable(CAP_SYS_ADMIN)) 102462306a36Sopenharmony_ci return -EACCES; 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci /* Find the key being removed. */ 102762306a36Sopenharmony_ci mk = fscrypt_find_master_key(sb, &arg.key_spec); 102862306a36Sopenharmony_ci if (!mk) 102962306a36Sopenharmony_ci return -ENOKEY; 103062306a36Sopenharmony_ci down_write(&mk->mk_sem); 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci /* If relevant, remove current user's (or all users) claim to the key */ 103362306a36Sopenharmony_ci if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) { 103462306a36Sopenharmony_ci if (all_users) 103562306a36Sopenharmony_ci err = keyring_clear(mk->mk_users); 103662306a36Sopenharmony_ci else 103762306a36Sopenharmony_ci err = remove_master_key_user(mk); 103862306a36Sopenharmony_ci if (err) { 103962306a36Sopenharmony_ci up_write(&mk->mk_sem); 104062306a36Sopenharmony_ci goto out_put_key; 104162306a36Sopenharmony_ci } 104262306a36Sopenharmony_ci if (mk->mk_users->keys.nr_leaves_on_tree != 0) { 104362306a36Sopenharmony_ci /* 104462306a36Sopenharmony_ci * Other users have still added the key too. We removed 104562306a36Sopenharmony_ci * the current user's claim to the key, but we still 104662306a36Sopenharmony_ci * can't remove the key itself. 104762306a36Sopenharmony_ci */ 104862306a36Sopenharmony_ci status_flags |= 104962306a36Sopenharmony_ci FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS; 105062306a36Sopenharmony_ci err = 0; 105162306a36Sopenharmony_ci up_write(&mk->mk_sem); 105262306a36Sopenharmony_ci goto out_put_key; 105362306a36Sopenharmony_ci } 105462306a36Sopenharmony_ci } 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci /* No user claims remaining. Go ahead and wipe the secret. */ 105762306a36Sopenharmony_ci err = -ENOKEY; 105862306a36Sopenharmony_ci if (is_master_key_secret_present(&mk->mk_secret)) { 105962306a36Sopenharmony_ci wipe_master_key_secret(&mk->mk_secret); 106062306a36Sopenharmony_ci fscrypt_put_master_key_activeref(sb, mk); 106162306a36Sopenharmony_ci err = 0; 106262306a36Sopenharmony_ci } 106362306a36Sopenharmony_ci inodes_remain = refcount_read(&mk->mk_active_refs) > 0; 106462306a36Sopenharmony_ci up_write(&mk->mk_sem); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci if (inodes_remain) { 106762306a36Sopenharmony_ci /* Some inodes still reference this key; try to evict them. */ 106862306a36Sopenharmony_ci err = try_to_lock_encrypted_files(sb, mk); 106962306a36Sopenharmony_ci if (err == -EBUSY) { 107062306a36Sopenharmony_ci status_flags |= 107162306a36Sopenharmony_ci FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY; 107262306a36Sopenharmony_ci err = 0; 107362306a36Sopenharmony_ci } 107462306a36Sopenharmony_ci } 107562306a36Sopenharmony_ci /* 107662306a36Sopenharmony_ci * We return 0 if we successfully did something: removed a claim to the 107762306a36Sopenharmony_ci * key, wiped the secret, or tried locking the files again. Users need 107862306a36Sopenharmony_ci * to check the informational status flags if they care whether the key 107962306a36Sopenharmony_ci * has been fully removed including all files locked. 108062306a36Sopenharmony_ci */ 108162306a36Sopenharmony_ciout_put_key: 108262306a36Sopenharmony_ci fscrypt_put_master_key(mk); 108362306a36Sopenharmony_ci if (err == 0) 108462306a36Sopenharmony_ci err = put_user(status_flags, &uarg->removal_status_flags); 108562306a36Sopenharmony_ci return err; 108662306a36Sopenharmony_ci} 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ciint fscrypt_ioctl_remove_key(struct file *filp, void __user *uarg) 108962306a36Sopenharmony_ci{ 109062306a36Sopenharmony_ci return do_remove_key(filp, uarg, false); 109162306a36Sopenharmony_ci} 109262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key); 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ciint fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *uarg) 109562306a36Sopenharmony_ci{ 109662306a36Sopenharmony_ci if (!capable(CAP_SYS_ADMIN)) 109762306a36Sopenharmony_ci return -EACCES; 109862306a36Sopenharmony_ci return do_remove_key(filp, uarg, true); 109962306a36Sopenharmony_ci} 110062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_ioctl_remove_key_all_users); 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci/* 110362306a36Sopenharmony_ci * Retrieve the status of an fscrypt master encryption key. 110462306a36Sopenharmony_ci * 110562306a36Sopenharmony_ci * We set ->status to indicate whether the key is absent, present, or 110662306a36Sopenharmony_ci * incompletely removed. "Incompletely removed" means that the master key 110762306a36Sopenharmony_ci * secret has been removed, but some files which had been unlocked with it are 110862306a36Sopenharmony_ci * still in use. This field allows applications to easily determine the state 110962306a36Sopenharmony_ci * of an encrypted directory without using a hack such as trying to open a 111062306a36Sopenharmony_ci * regular file in it (which can confuse the "incompletely removed" state with 111162306a36Sopenharmony_ci * absent or present). 111262306a36Sopenharmony_ci * 111362306a36Sopenharmony_ci * In addition, for v2 policy keys we allow applications to determine, via 111462306a36Sopenharmony_ci * ->status_flags and ->user_count, whether the key has been added by the 111562306a36Sopenharmony_ci * current user, by other users, or by both. Most applications should not need 111662306a36Sopenharmony_ci * this, since ordinarily only one user should know a given key. However, if a 111762306a36Sopenharmony_ci * secret key is shared by multiple users, applications may wish to add an 111862306a36Sopenharmony_ci * already-present key to prevent other users from removing it. This ioctl can 111962306a36Sopenharmony_ci * be used to check whether that really is the case before the work is done to 112062306a36Sopenharmony_ci * add the key --- which might e.g. require prompting the user for a passphrase. 112162306a36Sopenharmony_ci * 112262306a36Sopenharmony_ci * For more details, see the "FS_IOC_GET_ENCRYPTION_KEY_STATUS" section of 112362306a36Sopenharmony_ci * Documentation/filesystems/fscrypt.rst. 112462306a36Sopenharmony_ci */ 112562306a36Sopenharmony_ciint fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg) 112662306a36Sopenharmony_ci{ 112762306a36Sopenharmony_ci struct super_block *sb = file_inode(filp)->i_sb; 112862306a36Sopenharmony_ci struct fscrypt_get_key_status_arg arg; 112962306a36Sopenharmony_ci struct fscrypt_master_key *mk; 113062306a36Sopenharmony_ci int err; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci if (copy_from_user(&arg, uarg, sizeof(arg))) 113362306a36Sopenharmony_ci return -EFAULT; 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci if (!valid_key_spec(&arg.key_spec)) 113662306a36Sopenharmony_ci return -EINVAL; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved))) 113962306a36Sopenharmony_ci return -EINVAL; 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci arg.status_flags = 0; 114262306a36Sopenharmony_ci arg.user_count = 0; 114362306a36Sopenharmony_ci memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved)); 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci mk = fscrypt_find_master_key(sb, &arg.key_spec); 114662306a36Sopenharmony_ci if (!mk) { 114762306a36Sopenharmony_ci arg.status = FSCRYPT_KEY_STATUS_ABSENT; 114862306a36Sopenharmony_ci err = 0; 114962306a36Sopenharmony_ci goto out; 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci down_read(&mk->mk_sem); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci if (!is_master_key_secret_present(&mk->mk_secret)) { 115462306a36Sopenharmony_ci arg.status = refcount_read(&mk->mk_active_refs) > 0 ? 115562306a36Sopenharmony_ci FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED : 115662306a36Sopenharmony_ci FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */; 115762306a36Sopenharmony_ci err = 0; 115862306a36Sopenharmony_ci goto out_release_key; 115962306a36Sopenharmony_ci } 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci arg.status = FSCRYPT_KEY_STATUS_PRESENT; 116262306a36Sopenharmony_ci if (mk->mk_users) { 116362306a36Sopenharmony_ci struct key *mk_user; 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci arg.user_count = mk->mk_users->keys.nr_leaves_on_tree; 116662306a36Sopenharmony_ci mk_user = find_master_key_user(mk); 116762306a36Sopenharmony_ci if (!IS_ERR(mk_user)) { 116862306a36Sopenharmony_ci arg.status_flags |= 116962306a36Sopenharmony_ci FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF; 117062306a36Sopenharmony_ci key_put(mk_user); 117162306a36Sopenharmony_ci } else if (mk_user != ERR_PTR(-ENOKEY)) { 117262306a36Sopenharmony_ci err = PTR_ERR(mk_user); 117362306a36Sopenharmony_ci goto out_release_key; 117462306a36Sopenharmony_ci } 117562306a36Sopenharmony_ci } 117662306a36Sopenharmony_ci err = 0; 117762306a36Sopenharmony_ciout_release_key: 117862306a36Sopenharmony_ci up_read(&mk->mk_sem); 117962306a36Sopenharmony_ci fscrypt_put_master_key(mk); 118062306a36Sopenharmony_ciout: 118162306a36Sopenharmony_ci if (!err && copy_to_user(uarg, &arg, sizeof(arg))) 118262306a36Sopenharmony_ci err = -EFAULT; 118362306a36Sopenharmony_ci return err; 118462306a36Sopenharmony_ci} 118562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_ioctl_get_key_status); 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_ciint __init fscrypt_init_keyring(void) 118862306a36Sopenharmony_ci{ 118962306a36Sopenharmony_ci int err; 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci err = register_key_type(&key_type_fscrypt_user); 119262306a36Sopenharmony_ci if (err) 119362306a36Sopenharmony_ci return err; 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci err = register_key_type(&key_type_fscrypt_provisioning); 119662306a36Sopenharmony_ci if (err) 119762306a36Sopenharmony_ci goto err_unregister_fscrypt_user; 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_ci return 0; 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_cierr_unregister_fscrypt_user: 120262306a36Sopenharmony_ci unregister_key_type(&key_type_fscrypt_user); 120362306a36Sopenharmony_ci return err; 120462306a36Sopenharmony_ci} 1205