Linux KVM PPC HSTATE_HOST_R1 stack corruption (CVE-2020-8834)¶
CVE-2020-8834: POWER8 Book3S HV KVM'de, host stack pointer slot'u
HSTATE_HOST_R1hem HV entry path'i hem de transactional-memory save/restore helper'ları tarafından yeniden kullanılır, böylece guest TM aktivitesi host stack'i corrupt eder ve L0'ı panic'letir.
Mechanism¶
Bug class: kritik bir register'ın (host r1) aliased per-CPU storage'ı
Risk altındaki boundary ppc64'te (Book3S HV) guest kernel -> L0 host kernel'dir.
KVM, exit'te restore edilebilsin diye bir guest entry boyunca host stack pointer'ını
(r1) per-vCPU/per-CPU HSTATE_HOST_R1 slot'una saklar. Kırılan invariant
exclusivity'dir: o tek slot, ihtiyaç duyulduğu süre boyunca tam olarak bir live değer
tutmalıdır.
İki bağımsız code path HSTATE_HOST_R1'e yazar:
kvmppc_hv_entry(ana HV guest-entry sequence'ı), ve- transactional-memory helper'ları
kvmppc_save_tm/kvmppc_restore_tm.
Bir guest transactional memory (TM) tetiklediğinde, entry path'i hâlâ orada kendi
değerini beklerken TM helper'ları HSTATE_HOST_R1'i overwrite eder. Geri dönüş
yolunda host yanlış r1'i restore eder, dolayısıyla corrupt/yanlış bir stack
üzerinde resume eder — host kernel state'inin
out-of-bounds-write-class bir corruption'ı.
Dökümante edilmiş etki, bir guest'in kernel space'inde çalışan kod tarafından
tetiklenebilen bir host-kernel panic'idir (DoS).
Walkthrough¶
Public oss-security postundan ve Ubuntu/Launchpad raporlarından çıkarılan yüksek seviyeli reprodüksiyon şekli (POWER8 host, Book3S HV KVM, TM mevcut):
- Bir guest, transactional memory'nin expose edildiği bir POWER8 host'unda Book3S HV KVM altında çalışır.
- Guest kernel-mode kodu, KVM'in
kvmppc_save_tm/kvmppc_restore_tminvoke etmesine neden olan bir TM sequence'ı (ya da fake-suspend handling) sürer. - O helper'lar,
kvmppc_hv_entry'nin de host stack pointer'ını tutmak için kullandığıHSTATE_HOST_R1'i clobber eder. - Guest exit'inde host yanlış
r1'i restore eder ve corrupt bir stack üzerinde devam eder, bu da bir L0 panic'ine yol açar.
Fix, TM helper'larına kendi scratch storage'ını verir (örneğin HSTATE_SCRATCH2) ve
guest MSR'ı açıkça geçirir, böylece host r1 slot'u asla aliased olmaz.
Fix'in temsili şekli
Örnekleyici fragment
Patch niyetinin kavramsal temsili, birebir kopya değil. Tam assembly için atıf yapılan commit'lere bak.
Detection¶
- Book3S HV KVM çalıştıran POWER8 host'ları: özellikle transactional memory kullanan guest'lerle ilintili, backtrace'i TM save/restore ya da HV entry/exit kodundan geçen host-kernel panic'leri için dikkatli ol.
- Guest kernel space'inde TM instruction'larını tetikleyen spesifik tenant'lara bağlı crash'ler.
- POWER8'de 4.18'den önceki kernel'lerdeki host'lar (vuln 4.8 ve 4.17 boyunca tanıtıldı) varsayımsal olarak açıktır.
Mitigation¶
- Linux 4.18'de upstream düzeltildi (fix'in HV etkisi o sırada fark edilmeden).
Reporter'a göre strictly gerekli tek commit
6f597c6b63b6'dır ("KVM: PPC: Book3S PR: Add guest MSR parameter for kvmppc_save_tm()/kvmppc_restore_tm()"); aynı seride7b0e827c6970ve009c872a8bc4commit'leri de geldi ama bunlar strictly gerekli değil (yalnızca ilki yeterli kabul edilir). Not: commit başlığı "Book3S PR" der ama zafiyet Book3S HV'dedir — çünkükvmppc_save_tm/kvmppc_restore_tmTM helper'ları PR ve HV path'leri arasında paylaşılır; PR-refactor'ı olarak gelen bu commit paylaşılan helper'lara guest MSR parametresi ekleyipr1'i ayrı bir scratch slot'a taşıyarak HV conflict'ini de giderir (fix'in HV etkisi başlangıçta fark edilmemişti). Dağıtımının patch'li kernel'ini uygula (Ubuntu USN-4318-1, openSUSE-SU-2020:0543-1). - Guest'ler için transactional memory gerekmediği yerde, TM expose'unu disable etmek trigger'ı kaldırır.
- Bu flaw POWER8/Book3S-HV'ye özgüdür; x86 host'ları etkilenmez.