Skip to content

VMware virtual USB UHCI TOCTOU (CVE-2019-5519)

VMware'in emüle ettiği USB 1.1 UHCI controller'daki bir time-of-check/time-of-use race, bir guest'in bir descriptor field'ı validation ile use arasında değiştirmesine olanak tanıyarak host VMX memory'sini bozar ve guest-to-host code execution'a yol açar.

Mechanism

Bug class: paylaşılan guest UHCI schedule memory'si üzerinde TOCTOU double-fetch

Virtual USB 1.1 UHCI controller host VMX userworld'ünde emüle edilir, ama işlediği transfer schedule — frame list, Queue Head'ler ve Transfer Descriptor'lar — guest physical memory içinde yaşar. Bu memory, host emulator onu okurken guest tarafından writable kalmaya devam eder. Host bir field'ı (length, pointer, status) validate etmek için okuyup ardından aynı field'ı use anında tekrar okuduğunda, ikinci bir guest vCPU/thread bu iki read arasındaki pencerede değeri değiştirebilir.

Boundary aşılır çünkü emulator, guest tarafından yazılmış descriptor'ın bir transfer süresince stabil olduğunu örtük olarak varsayar. Değildir. Host, buffer'ına sığan bir değeri validate eder (time of check), ardından guest host onun üzerinde işlem yapmadan önce onu büyütür veya başka yere yönlendirir (time of use); böylece operasyon hiç validate edilmemiş bir değerle çalışır — host memory'de bir out-of-bounds copy ya da bir stale-pointer dereference.

İhlal edilen invariant şudur: bir check'ten sonra kullanılan, guest tarafından sağlanan herhangi bir field bir kez snapshot'lanmalı ve yalnızca snapshot validate edilip kullanılmalıdır. Root cause, mutable guest memory'sinin non-atomic double-fetch'idir; tek bir eksik bounds check değil — bu da onu aynı controller'daki düz OOB bug'tan (CVE-2019-5518) ayırır.

Walkthrough

Warning

Tarihsel ve patch'lenmiş (VMSA-2019-0005, 2019). Yalnızca public CVE/advisory'den kavramsal bir yeniden kurgu — offset, struct layout veya exploit yok.

  1. Guest, bir virtual USB controller'ı etkinleştirir ve UHCI'yı guest physical memory'deki bir schedule'a yönlendirir.
  2. Bir guest execution context'i (vCPU/thread), bir TD field'ını — örneğin bir transfer length'i — küçük bir "geçerli" değer ile büyük bir değer arasında tekrar tekrar değiştirir.
  3. Başka bir guest eylemi controller'ı ring eder; böylece host descriptor'ı küçük, range içindeki değeri gösterirken validate eder.
  4. Race halindeki writer, host data copy ya da pointer use işlemini yapmadan önce field'ı büyük/yeniden yönlendirilmiş değere çevirir; host operasyonu artık out of bounds veya bir stale pointer üzerinde çalışarak host memory'sini bozar.
Kavramsal race window (yalnızca örnekleme amaçlı)

host:  len = read(td.transfer_length)        // time-of-check: small, passes
       ...                                    // <-- guest flips field here
       copy(host_buf, src, read(td.transfer_length))  // time-of-use: large -> OOB
Yalnızca guest tarafından değiştirilebilen bir field'ın double-read'i load-bearing'dir; size ve offset'ler kasıtlı olarak çıkarılmıştır.

Detection

  • VMX crash'leri / core dump'lar: vmware.log içinde guest USB aktivite patlamalarıyla korele, kesintili ve yeniden üretilmesi zor vmware-vmx panic'leri (Backtrace/CoreDump/MonitorPanic), kazanılmış bir race'in imzasıdır.
  • ESXi vmkernel logları: bir VM için ara sıra vmx userworld sonlanmaları veya ZDUMP'lar; race'i kazanmak çok sayıda yeniden deneme gerektirdiği için genellikle kümelenir.
  • Behavioral sinyal: bir guest'in yüksek oranda UHCI ring/reset operasyonu yaparken birden çok vCPU'nun guest memory'deki aynı descriptor bölgesini hızla yeniden yazması anormaldir.
  • EDR / host telemetry: VM dizini altında tekrarlayan VM başına vmware-vmx restart'ları ve yeni core dump dosyaları.

Mitigation

  • VMSA-2019-0005'teki düzeltilmiş build'lere patch'leyin:
  • ESXi 6.0 / 6.5 / 6.7: ESXi600-201903001 / ESXi650-201903001 / ESXi670-201903001 (build'ler 13003896 / 13004031 / 13004448).
  • Workstation 14.x: 14.1.7; 15.x: 15.0.4.
  • Fusion 10.x: 10.1.6; 11.x: 11.0.3.
  • Attack surface'i azaltın (workaround): virtual USB 1.1 controller'ı VM'den kaldırın; bir virtual USB 2.0 controller'ı kaldırmak, onun örtük olarak eklediği USB 1.1 controller'ı da kaldırır.
  • OS/compiler defense: kalıcı düzeltme sınıfı, guest tarafından sağlanan her descriptor field'ını tam olarak bir kez host-private memory'ye snapshot'lamak, sonra yalnızca o snapshot'ı validate edip kullanmaktır (single-fetch); bu da race window'u ortadan kaldırır.

References