QEMU USB EHCI reachable assertion / DMA map failure DoS¶
QEMU'nun EHCI USB controller emülasyonundaki kontrol edilmeyen bir DMA-map failure, bir guest'in bir USB packet'i, sonraki
usb_packet_unmap()'in bir reachable assertion'a çarptığı bir state'e sürüklemesine ve host QEMU process'ini abort etmesine izin verir (CVE-2020-25723).
Mechanism¶
İzolasyon invariant'ı: başarısız bir DMA map host'u değil, transfer'i abort etmelidir
Bir USB transfer'i emüle etmek için EHCI, guest-physical buffer'ları (guest'in programladığı qTD/iTD data pointer'larından) dma_memory_map() çağıran usb_packet_map() üzerinden host'un kullanabileceği bir scatter/gather list'e map'ler. Bu map meşru olarak başarısız olabilir — örneğin guest, transfer'i map'lenemeyen bir adres aralığına (MMIO, map'lenemeyen bir delik veya tükenmiş bir bounce-buffer/IOMMU penceresi) yönelttiğinde. Controller'ın koruması gereken invariant şu: mapping başarısız olursa, packet'i temizce fail et.
EHCI model'i, usb_packet_map()'in return değerini kontrol etmiyordu. İşleme, buffer map'lenmiş gibi devam etti ve sonraki bir usb_packet_unmap() (veya hw/usb/hcd-ehci.c içindeki packet state'ini koruyan assertion), guest'in bozuk transfer'inin false hâle getirdiği bir assert()'e çarptı. assert(), abort() çağırdığı için, guest-controlled bir koşul, host QEMU process'ini deterministik olarak sonlandırır. Sınır aşımı, klasik "reachable assertion"dır: guest input, ulaşılamaz varsayılan bir host invariant'ına ulaşır.
Walkthrough¶
oss-security açıklamasına ve Red Hat Bugzilla 1898579'a dayanır; upstream'de usb_packet_map() return değerini kontrol ederek düzeltildi.
-
Guest, EHCI'ye bağlı bir USB device'ı ekler/kullanır (controller mevcut olmalıdır, örn.
-device usb-ehci). -
Guest, data buffer pointer'ı QEMU'nun bir host buffer'ına DMA-map edemediği guest-physical memory'yi referans alan bir transfer descriptor (qTD) kurar.
-
EHCI'nin transfer path'i, buffer'ı çevirmek için
usb_packet_map()çağırır; çağrı başarısız olur ama return değeri yok sayılır, böylece packet tutarsız bir state'te ilerler.Fix'in kavramsal şekli (map sonucunu kontrol et)
-
Patch'siz model'de transfer,
usb_packet_unmap()/ packet-state assertion'ına ulaşır, bu da false olarak değerlendirilir veabort()tetikler. -
Gözlemlenebilir sonuç: QEMU,
hw/usb/hcd-ehci.c'yi adlandıran bir assertion mesajı yazdırır ve QEMU process'i çıkar — guest içinden bir host denial of service.
Tarihî / patch'li
Düşük şiddetli DoS (host code execution yok), açıklanmış ve düzeltilmiş. Yalnızca patch'li/lab sistemlerde, yetkili defensive testing için kullan.
Detection¶
- Crash signature:
usb_packet_unmap/hw/usb/hcd-ehci.c'yi referans alan bir assertion failure ile QEMU'nun abort etmesi doğrudan parmak izidir. - Core/abort monitoring: QEMU'dan gelen
SIGABRT'yi bir security event olarak ele al; guest USB etkinliğiyle tetiklenen birassert()-driven çıkış anormaldir. - Fuzzing: qTD/iTD buffer pointer'larını map'lenemeyen aralıklara doğru mutate eden USB-controller fuzzing'i, bu ailedeki reachable-assertion bug'larını yeniden üretir; bkz. ../hypervisor/snapshot-based-greybox-hypervisor-fuzzing.md.
- Guest behavior: buffer'ları normal RAM dışına (MMIO/map'lenmemiş aralıklara doğru) düşen USB transfer'lerini tekrar tekrar programlayan bir guest şüphelidir.
Mitigation¶
- Patch:
usb_packet_map()return değerini kontrol eden ve sonradan assert etmek yerine transfer'i fail eden QEMU 5.2.0 veya sonrasına güncelle (fix commit2fdb42d840400d58f2e706ecca82c142b97bcbd6). - Reduce attack surface: USB gerekmedikçe bir EHCI controller'ı güvenilmeyen guest'lere açma; minimal/gerekli controller model'ini tercih et.
- Confinement: QEMU'yu seccomp (
-sandbox on) ve sVirt/SELinux'lü unprivileged bir uid altında çalıştır, böylece abort olmuş bir process contained olur ve management tooling tarafından host etkisi olmadan auto-restart edilir. - Operational: guest kaynaklı tekrarlayan QEMU abort'larını geçici crash'ler olarak ele almak yerine onlar için alert ver.