Skip to content

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):

  1. L0 host, KVM'yi kvm_amd nested=1 ile çalıştırır.
  2. Kötü niyetli/buggy bir L1 guest hypervisor bir L2 guest başlatır ama vmcb12'yi SHUTDOWN (triple fault) intercept'i set edilmeyecek şekilde configure eder.
  3. L2 bir triple fault tetikler (kullanılabilir bir IDT entry yokken oluşan herhangi bir kurtarılamaz fault).
  4. 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.
  5. 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 / oopskvm_vcpu_reset, shutdown_interception veya 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-kvm 5.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=0 veya /sys/module/kvm_amd/parameters/nested). Nested SVM, bu hata için tek attack surface'tir.

References