🇰🇷 한글 설명
Linux 커널의 KVM SEV 구현에서 메모리 해제 시 마스크 포인터를 초기화하지 않아 발생하는 이중 해제(Double-free) 취약점입니다. __sev_guest_init() 함수 실패 시 에러 경로에서 마스크가 해제된 후에도 포인터가 남아 있어, 이후 sev_vm_destroy()에서 동일한 메모리를 다시 해제하려고 시도할 수 있습니다.
💡 쉬운 설명
컴퓨터의 메모리를 관리하는 과정에서 이미 사용이 끝난 메모리 주소를 지우지 않아, 시스템이 같은 메모리를 두 번 삭제하려고 시도하는 오류입니다. 이로 인해 시스템이 불안정해지거나 보안 문제가 발생할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
KVM: SEV: Nullify "have run CPUs" mask pointer when freeing it
Nullify have_run_cpus when freeing the mask, particularly in the error path
of __sev_guest_init(), so that KVM doesn't have to subtly use sev->active
to track whether or not the mask has been freed. As pointed out by Sashiko,
blindly freeing the mask in sev_vm_destroy() results in a double-free if
the mask is freed if __sev_guest_init() fails.
Throw the logic in a helper as nullifying the pointer is frustratingly
difficult and weird due to have_run_cpus being a single-entry array when
CPUMASK_OFFSTACK=n. Deliberately don't use CPUMASK_VAR_NULL, as it's not
directly assignable when the cpumask is on-stack, e.g. requires using a
local variable and a memcpy(), which is beyond ridiculous. Furthermore,
while clearing the on-stack bitmask is an unnecessary and arguably unwanted
side effect, KVM absolutely relies on '0' being the "null" value given that
the struct is zero-allocated.
Opportunistically add an alloc() helper to pair with free(); there are just
enough call sites to make doing so worthwhile.
📍 영향받는 시스템
Linux Kernel (KVM SEV 기능이 활성화된 환경)
⚔️ 공격 벡터
로컬 공격자가 특수하게 조작된 SEV 가상 머신 초기화 과정을 통해 메모리 오류를 유도할 수 있음
🛡️ 대응 방법
KVM의 SEV 관련 메모리 관리 로직이 수정된 최신 Linux 커널 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 패치된 최신 버전인지 확인