QEMU e1000e DMA reentrancy use-after-free¶
QEMU'nun emüle Intel e1000e NIC'inde guest-to-host bir use-after-free (CVE-2023-3019); burada guest-programlanan DMA, device'ın kendi MMIO/işleme path'ine (
e1000e_write_packet_to_guest) re-enter ederek devam eden bir operasyonun içinden emulator state'ini free edip yeniden kullanır.
Mechanism¶
Note
QEMU device modelleri, guest RAM'e/RAM'den address_space_* helper'larıyla DMA
yapar. Bir device emulator için isolation invariant, bir DMA access'inin
emulator'ün kendi MMIO register'larını değil guest memory'sini hedeflemesidir.
DMA reentrancy bunu kırar: guest, DMA address'i device'ın kendi MMIO
region'una geri işaret eden bir device descriptor'ı programlar. Emulator DMA'yı
gerçekleştirdiğinde, access bir MMIO write olarak dispatch edilir ve bir dış
operasyon hâlâ stack üzerindeyken device'ın register-write handler'ına
re-enter eder. e1000e'de re-enter edilen handler, dış
e1000e_write_packet_to_guest() frame'inin hâlâ bir pointer tuttuğu state'i
(descriptor ring, packet context) ilerletebilir/free edebilir, böylece dış frame
ardından free edilmiş memory'yi dereference eder — tamamen guest kontrolünde bir
heap use-after-free. Host QEMU process'ini bozduğu için guest→host sınırını
aşar: en azından bir host DoS, potansiyel olarak host code execution.
Bu, daha geniş QEMU DMA-reentrancy bug sınıfının bir örneğidir; upstream mitigation,
biri zaten aktifken bir device'ın I/O dispatch'ine ikinci bir girişi reddeden
MemoryRegion başına bir mem_reentrancy_guard flag'idir.
Kardeş bug'tan farkı
Aynı DMA-reentrancy class'ı ama ayrı bir CVE'dir. Bu giriş e1000e NIC'i
(CVE-2023-3019) ve e1000e_write_packet_to_guest üzerinden free edilen
descriptor-ring/packet-context state'ini kapsar; NVMe varyantı
(QEMU NVMe DMA reentrancy use-after-free,
CVE-2021-3929) bunun yerine nvme_ctrl_reset() → nvme_free_sq() ile NVMe
submission/completion queue'larını free eder. Farklı subsystem, farklı CVE,
farklı free site — birbirinin duplicate'i değil.
Walkthrough¶
Public, hâlihazırda açıklanmış/patch'lenmiş materyal (Red Hat/SUSE advisory'leri, QEMU reentrancy-guard çalışması). Yalnızca kavramsal reproduction path — weaponize edilmiş bir chain yok.
- Guest, e1000e'yi ayağa kaldırır ve DMA target address'i normal guest RAM yerine e1000e'nin kendi MMIO BAR'ına ayarlanmış bir transmit/receive descriptor'ı inşa eder.
- Device descriptor'ı işler ve
address_space_*üzerinden bir DMA write çıkarır. Target MMIO olduğu için, write e1000e register-write callback'ine teslim edilir —e1000e_write_packet_to_guest()(ya da aynı chain'deki bir caller) mid-flight iken device'a re-enter ederek. - Re-enter edilen path, dış frame'in hâlâ referans verdiği ring ya da packet state'ini mutate eder/free eder; geri dönüşte dış frame free edilmiş object'i kullanır → use-after-free.
- Dikkatli guest tarafı timing/grooming ile free edilmiş slot yeniden ele geçirilebilir, UAF'yi kontrollü host-process corruption'a çevirir.
Warning
Bug sınıfı için belgelenmiş tarihsel, patch'lenmiş bir sorun. Bu giriş kavramsal kalır: hiçbir host heap layout, offset ya da end-to-end escape verilmez.
Bu sınıfı kapatan genel guard (örnekleyici şekil):
Reentrancy guard concept (mem_reentrancy_guard)
/* before dispatching an I/O access into a device region */
if (mr->dev && mr->dev->mem_reentrancy_guard.engaged_in_io) {
/* reject re-entry instead of recursing into the device */
return MEMTX_ACCESS_ERROR;
}
mr->dev->mem_reentrancy_guard.engaged_in_io = true;
/* ... perform access ... */
mr->dev->mem_reentrancy_guard.engaged_in_io = false;
Vulnerable bir build'de beklenen gözlemlenebilir: bir guest device DMA'sını device'ın
kendi MMIO'suna işaret ettiğinde e1000e path'inde qemu crash / ASan use-after-free.
Detection¶
- Host tarafı:
e1000e_write_packet_to_guestya da komşu e1000e DMA kodunda QEMU abort'ları / AddressSanitizer use-after-free raporları; guest NIC descriptor programlamasıyla ilişkilenen crash'ler. - Behavioral: target address'leri (RAM yerine) device MMIO içine düşen NIC DMA descriptor'larını yapılandıran bir guest, herhangi bir meşru driver için anormaldir.
Mitigation¶
- CVE-2023-3019 için QEMU fix'ini uygulayın ve
mem_reentrancy_guarddevice-reentrancy korumasını içeren bir build çalıştırın. - Bu attack surface'i daraltmak için untrusted guest'ler için emüle e1000e yerine virtio-net'i tercih edin.
- Defense-in-depth: QEMU process'ini sandbox'layın/deprivilege edin (seccomp, SELinux/sVirt) ki bir UAF, tam host compromise yerine sınırlanmış bir crash olsun.
References¶
- linuxpatch — CVE-2023-3019 (e1000e DMA reentrancy UAF) (arşiv kopyası): https://web.archive.org/web/20260309092906/https://linuxpatch.com/cve/CVE-2023-3019
- SUSE — CVE-2023-3019: https://www.suse.com/security/cve/CVE-2023-3019.html