fs/crypto/keyring.c
Source file repositories/reference/linux-study-clean/fs/crypto/keyring.c
File Facts
- System
- Linux kernel
- Corpus path
fs/crypto/keyring.c- Extension
.c- Size
- 39054 bytes
- Lines
- 1271
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
crypto/skcipher.hlinux/export.hlinux/key-type.hlinux/once.hlinux/random.hlinux/seq_file.hlinux/unaligned.hfscrypt_private.h
Detected Declarations
struct fscrypt_keyringfunction wipe_master_key_secretfunction move_master_key_secretfunction fscrypt_free_master_keyfunction fscrypt_put_master_keyfunction fscrypt_put_master_key_activereffunction absentfunction valid_key_specfunction fscrypt_user_key_instantiatefunction fscrypt_user_key_describefunction CONST_STRLENfunction format_mk_user_descriptionfunction allocate_filesystem_keyringfunction fscrypt_destroy_keyringfunction hlist_for_each_entry_safefunction fscrypt_mk_hash_bucketfunction fscrypt_put_master_keyfunction hlist_for_each_entry_rcufunction hlist_for_each_entry_rcufunction allocate_master_key_users_keyringfunction ERR_PTRfunction add_master_key_userfunction remove_master_key_userfunction add_new_master_keyfunction add_existing_master_keyfunction do_add_master_keyfunction add_master_keyfunction fscrypt_valid_key_sizefunction fscrypt_provisioning_key_preparsefunction fscrypt_provisioning_key_free_preparsefunction fscrypt_provisioning_key_describefunction fscrypt_provisioning_key_destroyfunction get_keyring_keyfunction fscrypt_ioctl_add_keyfunction fscrypt_get_test_dummy_secretfunction fscrypt_get_test_dummy_key_identifierfunction fscrypt_add_test_dummy_keyfunction fscrypt_verify_key_addedfunction shrink_dcache_inodefunction evict_dentries_for_decrypted_inodesfunction list_for_each_entryfunction check_for_busy_inodesfunction try_to_lock_encrypted_filesfunction FS_IOC_REMOVE_ENCRYPTION_KEYfunction fscrypt_ioctl_remove_keyfunction fscrypt_ioctl_remove_key_all_usersfunction fscrypt_ioctl_get_key_statusfunction fscrypt_init_keyring
Annotated Snippet
struct fscrypt_keyring {
/*
* Lock that protects ->key_hashtable. It does *not* protect the
* fscrypt_master_key structs themselves.
*/
spinlock_t lock;
/* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */
struct hlist_head key_hashtable[128];
};
static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
{
memzero_explicit(secret, sizeof(*secret));
}
static void move_master_key_secret(struct fscrypt_master_key_secret *dst,
struct fscrypt_master_key_secret *src)
{
memcpy(dst, src, sizeof(*dst));
memzero_explicit(src, sizeof(*src));
}
static void fscrypt_free_master_key(struct rcu_head *head)
{
struct fscrypt_master_key *mk =
container_of(head, struct fscrypt_master_key, mk_rcu_head);
/*
* The master key secret and any embedded subkeys should have already
* been wiped when the last active reference to the fscrypt_master_key
* struct was dropped; doing it here would be unnecessarily late.
* Nevertheless, use kfree_sensitive() in case anything was missed.
*/
kfree_sensitive(mk);
}
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);
if (mk->mk_users) {
/* Clear the keyring so the quota gets released right away. */
keyring_clear(mk->mk_users);
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,
Annotation
- Immediate include surface: `crypto/skcipher.h`, `linux/export.h`, `linux/key-type.h`, `linux/once.h`, `linux/random.h`, `linux/seq_file.h`, `linux/unaligned.h`, `fscrypt_private.h`.
- Detected declarations: `struct fscrypt_keyring`, `function wipe_master_key_secret`, `function move_master_key_secret`, `function fscrypt_free_master_key`, `function fscrypt_put_master_key`, `function fscrypt_put_master_key_activeref`, `function absent`, `function valid_key_spec`, `function fscrypt_user_key_instantiate`, `function fscrypt_user_key_describe`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.