QEMU SLIRP ip_reass use-after-free (CVE-2019-15890)¶
SLIRP üzerinden gönderilen özenle hazırlanmış fragmente bir IPv4 paketi, bir mbuf'u dequeue etmeden önce free eden libslirp'in IP reassembly drop path'inde bir use-after-free'ye yol açar.
Mechanism¶
Sınır neden bozuluyor
ip_reass() (slirp/src/ip_input.c, libslirp 4.0.0) drop path'inde,
sıraya alınmış bir fragment'i destekleyen mbuf, onu dequeue etmeden
(ip_deq()) önce free edilmişti (m_free(dtom(...))). Ardından gelen
dequeue, q->ipf_prev'i free edilmiş — muhtemelen yeniden ayrılmış — memory'ye
dereference etti. İhlal edilen invariant şu: bir object, destekleyen
memory'si serbest bırakılmadan önce tüm list'lerden unlink edilmelidir (NVD:
CWE-416). Bu, CVE-2019-14378 heap overflow'unun kardeş takip bug'ıdır ve aynı
fragment-reassembly yüzeyini paylaşır.
Walkthrough¶
Kavramsal, public advisory ve fix'ten.
- Guest, SLIRP user-mode networking kullanır.
- Guest,
ip_reass()'i drop/free path'ine sürükleyen özenle hazırlanmış fragmente IPv4 paketleri gönderir. - mbuf,
ip_deq()onu unlink etmeden önce free edilir → dangling pointer kullanımı (DoS, saldırgan tarafından etkilenebilen yeniden kullanılmış memory'nin okunması).
Detection¶
- Host-side: Guest fragmente-IPv4 trafiği sırasında QEMU crash; ASan,
ip_reassiçindeki use-after-free'yi işaretler. - Network telemetry: Bir guest'ten gelen anormal IPv4 fragmentation pattern'leri.
Mitigation¶
- Patch: libslirp > 4.0.0'da,
prev'i kaydedipm_free(...)'dan önceip_deq(prev)çağıran commitc59279437eda91841b9d26079c70b8a540d41204("ip_reass: Fix use after free") 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.