CVE-2022-49899

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
07/05/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> fscrypt: stop using keyrings subsystem for fscrypt_master_key<br /> <br /> The approach of fs/crypto/ internally managing the fscrypt_master_key<br /> structs as the payloads of "struct key" objects contained in a<br /> "struct key" keyring has outlived its usefulness. The original idea was<br /> to simplify the code by reusing code from the keyrings subsystem.<br /> However, several issues have arisen that can&amp;#39;t easily be resolved:<br /> <br /> - When a master key struct is destroyed, blk_crypto_evict_key() must be<br /> called on any per-mode keys embedded in it. (This started being the<br /> case when inline encryption support was added.) Yet, the keyrings<br /> subsystem can arbitrarily delay the destruction of keys, even past the<br /> time the filesystem was unmounted. Therefore, currently there is no<br /> easy way to call blk_crypto_evict_key() when a master key is<br /> destroyed. Currently, this is worked around by holding an extra<br /> reference to the filesystem&amp;#39;s request_queue(s). But it was overlooked<br /> that the request_queue reference is *not* guaranteed to pin the<br /> corresponding blk_crypto_profile too; for device-mapper devices that<br /> support inline crypto, it doesn&amp;#39;t. This can cause a use-after-free.<br /> <br /> - When the last inode that was using an incompletely-removed master key<br /> is evicted, the master key removal is completed by removing the key<br /> struct from the keyring. Currently this is done via key_invalidate().<br /> Yet, key_invalidate() takes the key semaphore. This can deadlock when<br /> called from the shrinker, since in fscrypt_ioctl_add_key(), memory is<br /> allocated with GFP_KERNEL under the same semaphore.<br /> <br /> - More generally, the fact that the keyrings subsystem can arbitrarily<br /> delay the destruction of keys (via garbage collection delay, or via<br /> random processes getting temporary key references) is undesirable, as<br /> it means we can&amp;#39;t strictly guarantee that all secrets are ever wiped.<br /> <br /> - Doing the master key lookups via the keyrings subsystem results in the<br /> key_permission LSM hook being called. fscrypt doesn&amp;#39;t want this, as<br /> all access control for encrypted files is designed to happen via the<br /> files themselves, like any other files. The workaround which SELinux<br /> users are using is to change their SELinux policy to grant key search<br /> access to all domains. This works, but it is an odd extra step that<br /> shouldn&amp;#39;t really have to be done.<br /> <br /> The fix for all these issues is to change the implementation to what I<br /> should have done originally: don&amp;#39;t use the keyrings subsystem to keep<br /> track of the filesystem&amp;#39;s fscrypt_master_key structs. Instead, just<br /> store them in a regular kernel data structure, and rework the reference<br /> counting, locking, and lifetime accordingly. Retain support for<br /> RCU-mode key lookups by using a hash table. Replace fscrypt_sb_free()<br /> with fscrypt_sb_delete(), which releases the keys synchronously and runs<br /> a bit earlier during unmount, so that block devices are still available.<br /> <br /> A side effect of this patch is that neither the master keys themselves<br /> nor the filesystem keyrings will be listed in /proc/keys anymore.<br /> ("Master key users" and the master key users keyrings will still be<br /> listed.) However, this was mostly an implementation detail, and it was<br /> intended just for debugging purposes. I don&amp;#39;t know of anyone using it.<br /> <br /> This patch does *not* change how "master key users" (-&gt;mk_users) works;<br /> that still uses the keyrings subsystem. That is still needed for key<br /> quotas, and changing that isn&amp;#39;t necessary to solve the issues listed<br /> above. If we decide to change that too, it would be a separate patch.<br /> <br /> I&amp;#39;ve marked this as fixing the original commit that added the fscrypt<br /> keyring, but as noted above the most important issue that this patch<br /> fixes wasn&amp;#39;t introduced until the addition of inline encryption support.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.4 (including) 5.10.154 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (including) 5.15.78 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.0.8 (excluding)