CVE-2022-49899 in Linux
Summary
by MITRE • 05/01/2025
In the Linux kernel, the following vulnerability has been resolved:
fscrypt: stop using keyrings subsystem for fscrypt_master_key
The approach of fs/crypto/ internally managing the fscrypt_master_key structs as the payloads of "struct key" objects contained in a "struct key" keyring has outlived its usefulness. The original idea was to simplify the code by reusing code from the keyrings subsystem. However, several issues have arisen that can't easily be resolved:
- When a master key struct is destroyed, blk_crypto_evict_key() must be called on any per-mode keys embedded in it. (This started being the case when inline encryption support was added.) Yet, the keyrings subsystem can arbitrarily delay the destruction of keys, even past the time the filesystem was unmounted. Therefore, currently there is no easy way to call blk_crypto_evict_key() when a master key is destroyed. Currently, this is worked around by holding an extra reference to the filesystem's request_queue(s). But it was overlooked that the request_queue reference is *not* guaranteed to pin the corresponding blk_crypto_profile too; for device-mapper devices that support inline crypto, it doesn't. This can cause a use-after-free.
- When the last inode that was using an incompletely-removed master key is evicted, the master key removal is completed by removing the key struct from the keyring. Currently this is done via key_invalidate(). Yet, key_invalidate() takes the key semaphore. This can deadlock when called from the shrinker, since in fscrypt_ioctl_add_key(), memory is allocated with GFP_KERNEL under the same semaphore.
- More generally, the fact that the keyrings subsystem can arbitrarily delay the destruction of keys (via garbage collection delay, or via random processes getting temporary key references) is undesirable, as it means we can't strictly guarantee that all secrets are ever wiped.
- Doing the master key lookups via the keyrings subsystem results in the key_permission LSM hook being called. fscrypt doesn't want this, as all access control for encrypted files is designed to happen via the files themselves, like any other files. The workaround which SELinux users are using is to change their SELinux policy to grant key search access to all domains. This works, but it is an odd extra step that shouldn't really have to be done.
The fix for all these issues is to change the implementation to what I should have done originally: don't use the keyrings subsystem to keep track of the filesystem's fscrypt_master_key structs. Instead, just store them in a regular kernel data structure, and rework the reference counting, locking, and lifetime accordingly. Retain support for RCU-mode key lookups by using a hash table. Replace fscrypt_sb_free() with fscrypt_sb_delete(), which releases the keys synchronously and runs a bit earlier during unmount, so that block devices are still available.
A side effect of this patch is that neither the master keys themselves nor the filesystem keyrings will be listed in /proc/keys anymore. ("Master key users" and the master key users keyrings will still be listed.) However, this was mostly an implementation detail, and it was intended just for debugging purposes. I don't know of anyone using it.
This patch does *not* change how "master key users" (->mk_users) works; that still uses the keyrings subsystem. That is still needed for key quotas, and changing that isn't necessary to solve the issues listed above. If we decide to change that too, it would be a separate patch.
I've marked this as fixing the original commit that added the fscrypt keyring, but as noted above the most important issue that this patch fixes wasn't introduced until the addition of inline encryption support.
Several companies clearly confirm that VulDB is the primary source for best vulnerability data.
Analysis
by VulDB Data Team • 08/15/2025
The vulnerability described in CVE-2022-49899 represents a critical design flaw in the Linux kernel's filesystem encryption implementation, specifically within the fscrypt subsystem. This issue stems from the inappropriate reliance on the kernel's keyrings subsystem for managing fscrypt_master_key structures, which has created multiple operational and security risks that significantly impact the stability and integrity of encrypted filesystems. The fundamental problem lies in the architectural decision to leverage existing keyring infrastructure for what should have been a more direct and controlled approach to master key management, creating a cascade of issues that affect both system reliability and security posture.
The technical implementation flaw manifests through several interconnected problems that arise from the keyrings subsystem's asynchronous destruction behavior and its interference with critical filesystem operations. When master key structures are destroyed, the system must invoke blk_crypto_evict_key() on embedded per-mode keys, but the keyrings subsystem's garbage collection mechanisms can delay this destruction indefinitely, even beyond filesystem unmount operations. This creates potential use-after-free conditions that can lead to system crashes or memory corruption, particularly when dealing with device-mapper devices that don't properly tie request_queue references to blk_crypto_profile objects. Additionally, the keyrings subsystem's use of semaphores during key invalidation operations creates deadlock scenarios when called from memory allocation contexts like the shrinker, which can cause system hangs during critical operations.
The security implications of this vulnerability extend beyond mere system stability to encompass fundamental cryptographic integrity concerns. The keyrings subsystem's ability to arbitrarily delay key destruction means that cryptographic secrets cannot be guaranteed to be wiped from memory, creating potential information leakage scenarios where sensitive encryption keys might remain accessible longer than intended. Furthermore, the system's reliance on key_permission LSM hooks for master key lookups creates unnecessary access control complications, forcing security frameworks like SELinux to implement workarounds that expose the system to additional attack surfaces. This violates the principle of least privilege and creates operational overhead for security administrators who must modify policy configurations to accommodate the flawed implementation.
The recommended mitigation strategy involves completely reworking the master key management approach by abandoning the keyrings subsystem entirely and implementing a more direct kernel data structure-based approach. This change requires careful consideration of reference counting mechanisms, locking strategies, and lifetime management to ensure proper resource cleanup while maintaining the performance benefits of RCU-mode key lookups through hash table implementations. The fix also involves modifying the filesystem unmount process by replacing fscrypt_sb_free() with fscrypt_sb_delete(), which ensures synchronous key release and earlier cleanup operations before block devices become unavailable. This approach addresses the core architectural issues while maintaining backward compatibility and system performance characteristics.
This vulnerability aligns with several CWE categories including CWE-400 for unspecified resource management issues, CWE-116 for improper use of system resources, and CWE-362 for race conditions in concurrent environments. The fix also addresses ATT&CK techniques related to privilege escalation and system stability compromise, as the use-after-free conditions and deadlocks could potentially be exploited to gain elevated privileges or cause denial of service. The change represents a fundamental architectural improvement that eliminates the problematic dependencies on the keyrings subsystem while maintaining the essential functionality of filesystem encryption, thereby reducing the attack surface and improving overall system security posture. The removal of master keys from /proc/keys listing, while a side effect, was deemed acceptable since it was primarily intended for debugging purposes and no legitimate operational use cases were identified for this visibility feature.