Skip to content

QEMU e1000 TX-descriptor infinite loop (CVE-2021-20257)

Invalid field değerlerine sahip malformed e1000 transmit descriptor'ları, QEMU'nun process_tx_desc'inde aritmetik bir underflow tetikler, sonsuza dek döngüye girip host CPU'sunu tüketir — guest-to-host bir denial of service.

Mechanism

Sınır neden kırılıyor

QEMU, Intel e1000 NIC'ini (hw/net/e1000) host process içinde emüle eder. Guest transmit ettiğinde, process_tx_desc TX descriptor ring'ini dolaşır, segment data'sını biriktirir ve offset'leri bir maximum-segment header uzunluğuna (msh) karşı izler. Hata, bir driver data descriptor'ları legacy descriptor'larla zincirlediğinde ve descriptor field'larını invalid değerlerle initialize ettiğinde ortaya çıkar: bir byte-count hesabı underflow edebilir, böylece size bookkeeping beklenen sınırın ötesine asla ilerlemez ve işleme mantığı sonlanmaz. Bu, memory corruption değil, bir erişilemez çıkış koşuluna sahip döngü (CWE-835)'dür: hiçbir şey üzerine yazılmaz, ama QEMU/vCPU thread'i %100'de dönerek host CPU'sunu tüketir. İhlal edilen invariant şudur: guest tarafından sağlanan descriptor field'ları, loop-termination aritmetiğine beslenmeden önce validate edilmelidir ki herhangi bir descriptor stream'inin emülasyonu her zaman dursun. Etki, host availability'ye karşı bir denial of service'tir.

Walkthrough

Public CVE/Bugzilla ve upstream fix commit'inden kavramsal yeniden kurgu; yalnızca mantıksal adımlar.

  1. Host, emüle bir e1000 NIC'e sahip bir guest çalıştırır.
  2. Privileged bir guest aktörü, TX descriptor ring'ini malformed bir kombinasyonla programlar — data descriptor'ları bir legacy descriptor'la zincirleyip descriptor field'larını, size accounting'i underflow ettiren invalid değerlere ayarlayarak.
  3. process_tx_desc içinde, underflow olan size sonlanma koşulunu asla sağlamaz, böylece host işlemeyi süresiz tekrarlar — host CPU spin / denial of service.
Root cause and fix logic

The upstream fix adds an early bail-out before the underflow-prone arithmetic, terminating processing of the malformed descriptor:

if (tp->size >= msh) {
    goto eop;   /* fail early instead of underflowing */
}

"An infinite loop flaw was found in the e1000 NIC emulator of the QEMU. This issue occurs while processing transmits (tx) descriptors in process_tx_desc if various descriptor fields are initialized with invalid values." — NVD CVE-2021-20257

Detection

  • Host CPU spin: Guest e1000 TX aktivitesiyle ilişkilenen, network ilerlemesi olmadan %100'de takılı bir QEMU/vCPU thread'i anahtar göstergedir (top, perf top, hung-task / soft-lockup tarzı watchdog'lar).
  • Stack inspection: Bir debugger, host thread'inin process_tx_desc / start_xmit içinde döngüye girdiğini gösterir.
  • Telemetry: Data ve legacy descriptor'ları tutarsız length field'larıyla zincirleyen TX ring'leri programlayan guest'ler anormaldir ve enstrümante bir device modeli tarafından loglanabilir.

Mitigation

  • Patch: tp->size >= msh'i kontrol edip erken fail eden ve underflow-driven döngüyü önleyen upstream QEMU fix'ini (commit 3de46e6fc489c52c9431a8a832ad8170a7569bd8) uygulayın. QEMU 6.2.0 ve sonrasında çözüldü.
  • Configuration workaround: Mümkün olan yerde untrusted guest'ler için emüle e1000 device'ı yerine virtio-net'i tercih edin; bu kod path'ine sahip değildir.
  • Sandboxing / containment: QEMU'yu seccomp (-sandbox on) ve svirt confinement altında çalıştırın; QEMU process'ine cgroup CPU quota'ları uygulayın ki kaçak bir emülasyon thread'i host'un geri kalanını aç bırakamasın.

References