KVM AMD nested virtualization DoS¶
CVE-2022-3344: kötü niyetli bir L1 hypervisor bir L2 shutdown/triple-fault'unu intercept etmeyi reddeder; bu da KVM'nin vCPU'yu hâlâ nested mode'dayken reset etmesine ve L0 host'un çökmesine yol açar.
Mechanism¶
Bug sınıfı: nested boundary'de state-machine confusion
Bu, KVM'nin AMD SVM nested virtualization'ındaki bir nested-state cleanup ordering hatasıdır. Risk altındaki isolation boundary L1 guest -> L0 host: bir guest hypervisor (L1) içinde çalışan kod, host kernel'i (L0) tutarsız bir iç state'e sürükler ve sonuç host'un çökmesidir.
AMD SVM'de (Intel VMX'in aksine) iki gerçek tehlikeli şekilde bir araya gelir:
- INIT/shutdown event'leri non-root (guest) mode'da latch'lenmez.
- L1, L2'de oluşan bir triple fault'u (
SHUTDOWN) intercept etmek zorunda değildir.
L2 triple-fault verdiğinde ve L1 onu intercept etmemeyi seçtiğinde, KVM'nin
shutdown_interception() handler'ı, nested control block (vmcb02) üzerinden
çalışan ve hâlâ guest mode'da olan bir vCPU için kvm_vcpu_reset()'e ulaşır.
kvm_vcpu_reset() önce nested "leave" path'ini çağırmadan doğrudan
vcpu->arch.hflags'i temizler; böylece vCPU yarı-içeride / yarı-dışarıda, nested
mode arasında kalır. Daha sonraki bir transition (örneğin EFER.SVME'nin
temizlenmesi) vmcb02'yi free eden nested teardown'u tetikler, ancak başka kod
path'leri hâlâ ona referans verir — kernel context'inde bir use-after-free /
NULL-deref, L0'da panic'e neden olur.
Intel VMX'te aynı tetikleyici oluşamaz çünkü VMX triple fault'ları her zaman intercept eder, onları L1'e yönlendirir ve VMX'in triple-fault handler'ı vCPU'yu reset etmez.
Walkthrough¶
Kavramsal reproduction path (AMD host'ta nested SVM'in enable olmasını gerektirir):
- L0 host, KVM'yi
kvm_amd nested=1ile çalıştırır. - Kötü niyetli/buggy bir L1 guest hypervisor bir L2 guest başlatır ama
vmcb12'yiSHUTDOWN(triple fault) intercept'i set edilmeyecek şekilde configure eder. - L2 bir triple fault tetikler (kullanılabilir bir IDT entry yokken oluşan herhangi bir kurtarılamaz fault).
- L1 onu intercept etmediği için, KVM hâlâ nested olan vCPU için shutdown'u handle eder ve nested mode'dan çıkmadan onu reset eder.
- Sonraki guest aktivitesi KVM'yi
vmcb02'yi free eden nested teardown'a sürükler; dangling referans L0'da bir kernel panic'e neden olur.
Upstream fix (commit ed129ec9057f89d615ba0c81a4984a90345a1684,
"KVM: x86: forcibly leave nested mode on vCPU reset") explicit bir nested-leave artı
kvm_vcpu_reset() içinde bir guard ekler:
Representative shape of the fix (arch/x86/kvm/x86.c)
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
{
/* ... */
/* Forcibly drop out of nested mode BEFORE clearing hflags so the
* vCPU can never be reset while still running off vmcb02. */
kvm_leave_nested(vcpu);
/* ... existing reset of registers / hflags ... */
WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
}
Beklenen etki: fix'ten sonra bir vCPU reset her zaman önce nested mode'dan
çıkar, böylece vmcb02'ye teardown sonrasında asla referans verilmez ve host
artık panic vermez; WARN_ON_ONCE, vCPU'yu guest/SMM mode'da bırakan gelecekteki
her regression'ı yakalar.
Açıklayıcı fragment
Yukarıdaki code block, public patch'in temsili bir şeklidir, birebir kopyası değildir. Kesin satırlar için atıf yapılan commit'e bakın.
Detection¶
- Nested virtualization'a izin veren (
kvm_amd nested=1) AMD host'larda KVM SVM nested kodundan kaynaklanan host kernel panic / oops —kvm_vcpu_reset,shutdown_interceptionveya nested-SVM teardown üzerinden geçen backtrace'lere bakın. - Kendisi VM çalıştıran bir guest (L1 hypervisor workload'ları) ile ilişkili crash.
- Filo izleme için: fix deploy edildikten sonra
WARN_ON_ONCE(is_guest_mode(vcpu) ...)üzerine alert kurun — tam olarak bu tutarsız-state koşulunda fire eder. - Hangi tenant'lara nested virtualization'a izin verildiğini hiç audit edin; nesting disable olduğunda bug erişilemezdir.
Mitigation¶
- Commit
ed129ec9057f89d615ba0c81a4984a90345a1684("KVM: x86: forcibly leave nested mode on vCPU reset") ile upstream'de düzeltildi, Linux 6.1 için merge edildi ve stable tree'lere backport edildi. - Distro fix'leri arasında Fedora kernel 6.0.11+ ve Ubuntu
linux-image-5.19.0-1019-kvm5.19.0-1019.20 (USN-5950-1) bulunur. Distribution'ınızın yamalanmış kernel'ini uygulayın. - Workaround: güvenilmeyen guest'ler için nested virtualization'ı disable edin
(
modprobe kvm_amd nested=0veya/sys/module/kvm_amd/parameters/nested). Nested SVM, bu hata için tek attack surface'tir.