🇰🇷 한글 설명
Linux 커널의 fscrypt가 마스터 키 관리를 위해 keyrings 서브시스템을 사용함으로써 발생하는 설계 결함입니다. 이로 인해 키 파괴 시점이 지연되어 Use-After-Free 취약점이 발생하거나, 메모리 할당 과정에서 데드락(Deadlock)이 발생할 수 있습니다.
💡 쉬운 설명
암호화 키를 관리하는 방식이 잘못되어 시스템이 멈추거나, 이미 삭제된 데이터에 접근하여 보안 문제가 생길 수 있는 오류입니다. 키가 제때 삭제되지 않아 중요한 정보가 메모리에 남아있을 위험도 있습니다.
🇺🇸 원문 (English)
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.
📍 영향받는 시스템
Linux kernel (fscrypt 및 inline encryption 사용 환경)
⚔️ 공격 벡터
특정 조건에서 파일 시스템 언마운트 및 키 삭제 시 발생하는 메모리 관리 오류를 이용한 Use-After-Free 또는 데드락 유도
🛡️ 대응 방법
fscrypt 마스터 키 관리를 keyrings 서브시스템 대신 커널 내부 데이터 구조로 변경한 최신 Linux 커널로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 패치된 최신 보안 업데이트 버전인지 확인