QEMU virtio-snd heap buffer overflow (virtio_snd_pcm_in_cb)¶
CVE-2024-7730: QEMU'nun virtio-snd PCM input callback'indeki eksik bir maximum-size bounds check, receive iovec'inde audio data için yer olmadığında bir guest'in host tarafı bir heap buffer overflow'u zorlamasına izin veriyor.
Mechanism¶
Note
Bir virtio device guest tarafından virtqueue'lar üzerinden sürülür: guest
scatter/gather descriptor'ları (bir iovec) gönderir ve host device model'i
onları doldurur. PCM input (capture) path'i için host, iovec'in toplam
kapasitesini katı bir tavan olarak ele almalı ve onun ötesine asla yazmamalıdır.
QEMU'nun virtio_snd_pcm_in_cb()'i bunun yerine buffer başına buffer->size
field'ını çalışan bir şimdiye-kadar-toplam akümülatör'ü olarak kullandı
(transmit path'inin kaçındığı pattern) ve audio'yu hiçbir zaman iovec'in gerçek
boyutuyla karşılaştırmadan döngüyle yazdı. Guest, toplam uzunluğu
sizeof(virtio_snd_pcm_status)'a (8 byte'lık status footer'ı) eşit bir in_sg
iovec yayımladığında, audio data için kullanılabilir alan sıfırdır — yine de
callback audio'yu AUD_read ile buffer'a okumaya devam eder ve host allocation'ının
ötesine yazar. Toplam uzunluk sizeof(virtio_snd_pcm_status)'tan küçük
olduğunda ise iov_size(...) - sizeof(virtio_snd_pcm_status) çıkarması bir
integer underflow yapar, dolayısıyla sorun yalnızca eşitlik değil bu
underflow case'ini de kapsar. İzolasyon sınırı geçilir çünkü guest'in sağladığı
descriptor geometrisi doğrudan host (QEMU process) heap write'larını yönlendirir.
Walkthrough¶
Kavramsal, halihazırda patch'lenmiş path (public materyal: GitLab issue #2427, fix
commit 98e77e3d ve osec.io writeup'ı).
- Geometri: guest,
in_sg/in_num'u toplam boyutu== sizeof(virtio_snd_pcm_status)(8 byte) olan bir iovec tanımlayan bir RX virtqueue element'i enqueue eder ve sıfır data kapasitesi bırakır. - Allocation: host data region'ını
iov_size(in_sg, in_num) - sizeof(virtio_snd_pcm_status)'tan boyutlandırır. iovec tam olarak 8 byte olduğunda bu 0 byte'tır; guest iovec'isizeof(virtio_snd_pcm_status)(8 byte)'dan küçük yaptığında iseiov_size(...) - sizeof(virtio_snd_pcm_status)çıkarması bir integer underflow yapar; unsigned arithmetic'te sonuç çok büyük bir değere wrap'lenir ve hesaplanan "kalan kapasite" gerçek alandan kopar — yani sorun yalnızca eşitlik (==) değil,iov_size(...) < sizeof(virtio_snd_pcm_status)underflow case'ini de kapsar. - Overflow:
virtio_snd_pcm_in_cb()capture loop'unu çalıştırır ve gelen audio'yu gerçek (sıfır) kapasiteyi hesaba katmayan bir limitleAUD_readüzerinden yazar, audio byte'larını küçük boyutlu chunk'ın ötesine taşırır. - Corruption: komşu glibc heap metadata'sı bozulur. osec.io araştırması
0x200boyutunda bir komşu (bir virtio-9p xattr değeri) groom eder ve daha fazla heap exploitation'ı bootstrap etmek için onun size field'ını bozar.
Fix, herhangi bir write öncesinde eksik tavanı ekler:
max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num);
for (;;) {
if (buffer->size >= max_size) {
return_rx_buffer(stream, buffer);
break;
}
/* ... AUD_read into the remaining space ... */
}
Warning
Overflow içeriği audio stream'idir — saldırgan tarafından etkilenir ama tam olarak keyfi değildir — bu yüzden bu, kontrole ulaşmak için hassas heap grooming ile eşleştirilmesi gereken bir uncontrolled overflow'dur. CVE-2026-3195 aynı callback'in eksik bir fix regresyonudur; herhangi bir backport'un gerçekten her write'ı bound ettiğini doğrulayın.
Detection¶
- Host/sandbox: QEMU'yu ASan/
-fsanitize=addressaltında çalıştırın;hw/audio/virtio-snd.ciçindeki OOB write hemen bir heap-buffer-overflow olarak işaretlenir (fuzzing issue #2427'yi tam olarak böyle yüzeye çıkardı). virtio-sndiçin toplam uzunluğu status footer boyutuna eşit (data room yok) RX descriptor'ları yayımlayan bir guest, bir device-model monitor'ün loglayabileceği anormal, şüpheli bir pattern'dir.virtio-sndcapture aktivitesiyle korele QEMU crash'leri/abort'larını izleyin.
Mitigation¶
- Patch: fix commit
98e77e3d(QEMU ≥ 9.1.0)'i ve CVE-2026-3195 takibini uygulayın; input callback'in her write'ıiov_size(in_sg, in_num)ile bound ettiğinden emin olun. - Attack surface reduction: Gerekli olmadıkça
virtio-snd'yi untrusted guest'lere açmayın; audio capture'a ihtiyaç duymayan VM config'lerinden device'ı kaldırın. - Defense in depth: Host tarafı bir overflow'un minimum blast radius'una sahip
olması için QEMU'yu sandboxed (seccomp,
-sandbox on), düşük ayrıcalıklı confined bir process olarak (SELinux/AppArmorsvirt) çalıştırın.
References¶
- NVD — CVE-2024-7730
- Red Hat Bugzilla 2304289 (CVE-2024-7730)
- QEMU fix commit 98e77e3d — virtio-snd: add max size bounds check in input cb
- QEMU issue #2427
- osec.io — From virtio-snd 0-Day to Hypervisor Escape
- Ubuntu USN-8161-1 — QEMU vulnerabilities (CVE-2026-3195, incomplete fix for CVE-2024-7730)
- NVD — CVE-2026-3195 (virtio-snd input cb incomplete fix for CVE-2024-7730)