QEMU NIC loopback DMA-reentrancy infinite loop (CVE-2021-3416)¶
Loopback mode'da, birkaç QEMU NIC emulator'ü transmit edilen bir frame'i kendi receive path'lerine geri teslim eder; böylece reentrant-DMA check'leri bypass edilir ve host QEMU process'ini crash'leyen bir infinite loop / stack overflow üretilir.
Mechanism¶
Isolation invariant: transmit, aynı device'ta receive'i senkron olarak re-enter etmemeli
Emule edilmiş NIC'ler bir internal loopback uygular: guest device'ı loopback'e programladığında, model'in transmit ettiği bir frame doğrudan aynı model'in receive routine'ine geri beslenir. Örtük invariant, delivery'nin bounded olmasıdır — bir transmit en fazla sonlu miktarda receive işi üretir ve aynı stack üzerinde recursive olarak daha fazla transmit tetiklemez.
Vulnerable NIC model'leri, device'ın kendi receive function'ını transmit path'inden doğrudan çağırıyordu. Loopback'te bu doğrudan çağrı device'ı re-enter eder ve reentrant DMA'yı tespit etmesi gereken guard bypass edilir; dolayısıyla tek bir guest-initiated transmit, unwind olmadan kendine sürekli frame teslim edip durabilir. Sonuç, CPU'yu ya da host stack'ini tüketen unbounded bir loop / derin recursion'dır. Bu, guest→host sınırını aşar çünkü loop host QEMU process'inde çalışır. ../hypervisor/qemu-tulip-device-dma-reentrancy.md'deki descriptor-loop reentrancy ve ../hypervisor/qemu-address-space-map-dma-reentrancy-reentry-into-device.md'deki DMA-reentry ailesiyle aynı class'tır.
Walkthrough¶
CVE-2021-3416 olarak disclose ve patch edildi: loopback reentrant-DMA check'lerini bypass ettiğinde çeşitli QEMU NIC emulator'lerinde infinite loop yoluyla bir stack overflow. Fix, loopback delivery'sini reentrancy'yi tespit eden ve recurse etmek yerine erken dönen qemu_receive_packet() üzerinden yönlendirir. Aşağıdaki path kavramsaldır, public advisory'den alınmıştır.
-
Guest, etkilenen bir emule edilmiş NIC'i sürer ve device'ın loopback mode'unu control register'ları aracılığıyla etkinleştirir.
-
Guest bir transmit'i kick eder. Model'in TX path'i, loop'lanan frame'i "teslim etmek" için device'ın kendi receive routine'ini doğrudan çağırır.
-
Delivery hiçbir zaman yatışmaz: device aynı stack üzerinde transmit-sonra-receive-sonra-transmit yapar. QEMU vCPU thread'i spin yapar (CPU exhaustion) ya da host stack'i overflow olur ve process fault'a girer (DoS). Advisory etkiyi guest-triggered CPU consumption veya bir host QEMU crash'i olarak kapsamlandırır.
Tarihsel / patch'lenmiş
Yalnızca yetkili defensive research ve regression testing içindir. Fragment re-entry şeklini gösterir, weaponize edilmiş bir chain'i değil. Patch'lenmemiş QEMU'ya karşı untrusted guest'ler çalıştırma.
Detection¶
- Crash signature: backtrace'i aynı device'ın transmit ve receive function'larının çok kez dönüşümlü çalıştığını gösteren bir QEMU SIGSEGV, kanonik stack-overflow fingerprint'idir.
- CPU anomalisi: tek bir guest'in bir vCPU thread'ini ileri ilerleme olmadan %100'de pin'lemesi, guest'in NIC loopback'i etkinleştirmesiyle korele olarak, daha yumuşak ama daha erken bir sinyaldir.
- Runtime guard tripping: patch'lenmiş QEMU'da
qemu_receive_packet()reentrant delivery'yi tespit eder ve erken döner; bu erken-dönüşü loglamak, kötü niyetli loopback girişimlerini yüzeye çıkarır. - Fuzzing: loopback'i toggle eden ve TX'i kick eden structured net-device fuzzing bu class'ı hızlıca reproduce eder. Bkz. ../hypervisor/hypercall-fuzzing.md.
Mitigation¶
- Patch: etkilenen NIC model'leri genelinde loopback delivery'sini
qemu_receive_packet()'e (reentrancy-aware) geçiren CVE-2021-3416 serisini taşıyan bir QEMU sürümüne güncelle. - Defense in depth: emule edilen model'in gerekli olmadığı yerlerde legacy emulated NIC'ler yerine paravirtualized virtio-net'i tercih et; machine type'taki kullanılmayan NIC model'lerini devre dışı bırak.
- Confinement: QEMU'yu sandbox'lanmış olarak (
-sandbox onseccomp, unprivileged uid, SELinux/sVirt) çalıştır; böylece suistimal edilen bir device model, VM'in process'inin ötesine pivot edemez. - Operational: guest-induced bir host QEMU crash'ini veya runaway bir vCPU'yu, bir stability bug'ı değil, bir security event olarak ele al.