QEMU SLIRP ip_reass heap overflow (CVE-2019-14378)¶
SLIRP ("user") networking üzerinden gönderilen özenle hazırlanmış, büyük, fragmente bir IPv4 paketi, ilk fragment'in boyutu yanlış işlendiği için libslirp'in IP reassembly'sinde bir heap overflow'a yol açar.
Mechanism¶
Sınır neden bozuluyor
SLIRP, fragmente IPv4 paketlerini ip_reass() (slirp/src/ip_input.c,
libslirp 4.0.0) içinde reassemble eder. İlk fragment inline mbuf
buffer'ından (m_dat[]) büyük olduğunda, mbuf harici bir backing'e (m_ext)
geçirilir, ancak reassembly trim/copy aritmetiği hâlâ inline layout'u varsayar.
İhlal edilen invariant şu: fragment offset'leri ve copy uzunlukları, gerçek
mbuf backing'ine ve ilk fragment'in belirlediği payload sınırlarına karşı
validate edilmelidir. Sonraki fragment'lerin bu sınırlar içinde kaldığı
doğrulanmadığı için copy, host heap allocation'ının ötesine yazar (NVD:
CWE-787 OOB write, CWE-755). Sonuç: host QEMU crash, potansiyel RCE.
Walkthrough¶
Kavramsal, public advisory ve fix'ten.
- Guest, SLIRP user-mode networking kullanır (
-netdev user,...). - Guest, ilk fragment'in inline mbuf buffer'ını aştığı, özenle hazırlanmış fragmente IPv4 paketleri gönderir.
ip_reass(), harici backing'li bir mbuf üzerinde inline-layout varsayımlarıyla reassemble eder → heap OOB write.
Detection¶
- Host-side: Guest network etkinliği sırasında QEMU crash; ASan/heap-guard,
ip_reassiçindeki OOB'yi işaretler. - Network telemetry: Bir guest'ten gelen anormal IPv4 fragmentation (olağandışı ilk fragment boyutları / örtüşen fragment'ler).
Mitigation¶
- Patch: libslirp > 4.0.0'da, out-of-bounds fragment'leri düşüren commit
126c04acbabd7ad32c2b018fe10dfac2a3bc1210("Do not reassemble fragments pointing outside of the original payload") ile düzeltildi. - Configuration workaround: Güvenilmeyen guest'ler için SLIRP yerine bir tap/bridge backend'i tercih et veya gerekmediğinde user-mode networking'i devre dışı bırak.