Skip to content

QEMU virtio_crypto_sym_op_helper heap overflow (src_len/dst_len)

CVE-2023-3180: QEMU'nun virtio-crypto symmetric request handler'ı source ve destination uzunluklarının eşleşip eşleşmediğini hiç kontrol etmiyordu, bu yüzden bir guest src_len/dst_len'i uyuşmaz hale getirip bir host heap buffer'ını overflow edebiliyordu.

Mechanism

Note

Bir symmetric cipher işlemi için ciphertext uzunluğu plaintext uzunluğuna eşit olmalıdır: bir input block bir output block'a karşılık gelir. QEMU'nun virtio-crypto device'ı her symmetric request için guest'in sağladığı src_len (source data) ve dst_len (destination/result) değerlerinden bir op_info inşa eder, ardından bu uzunluklara göre allocate edip kopyalar. virtio_crypto_sym_op_helper() src_len == dst_len olduğunu hiçbir şekilde kontrol etmiyordu (makul bir birleşik bound da yoktu). Bir guest dolayısıyla küçük bir allocation bildirip diğer field tarafından boyutlandırılmış bir kopyayı sürebilir — ya da tersi — ve host buffer'ının ötesine yazabilirdi. Sınır geçiliyor çünkü guest, cipher verisinin host'taki g_malloc/memcpy'sini boyutlandıran ve sınırlayan her iki uzunluk field'ını da tamamen kontrol ediyor.

Walkthrough

Kavramsal, halihazırda patch'lenmiş path (public materyal: Red Hat Bugzilla 2222424, fix commit 9d38a843).

  1. Request: guest, request header'ında ayrı src_len ve dst_len sağlayarak virtio_crypto_handle_sym_req aracılığıyla bir virtio-crypto symmetric (cipher) request gönderir.
  2. Invariant yok: virtio_crypto_sym_op_helper() guest uzunluklarından birleşik bir max_len hesaplar ve src_len == dst_len'i zorlamadan op_info'yu doldurur.
  3. Mismatch: src_len != dst_len yaparak, bir uzunluktan boyutlandırılmış host buffer'ı diğeriyle sınırlanmış veriyle yazılır, host tarafı allocation'ı overflow eder (ya da komşu belleği leak eder).
  4. Etki: QEMU process heap'inde out-of-bounds write → denial of service ve potansiyel olarak host code execution (CVSS 6.5, "important").

Fix, herhangi bir allocation/kopya öncesinde uyuşmayan uzunlukları reddeder:

if (unlikely(src_len != dst_len)) {
    virtio_error(vdev, "sym request src len is different from dst len");
    return NULL;
}

Warning

Bug çok eskiden, v2.8.0-rc0'da girmişti ve yalnızca QEMU 8.1.0'da düzeltildi (backport v8.0.4). Distro paketleri geriden geliyor; yalnızca bir versiyon numarasına değil, src_len != dst_len guard'ının var olduğuna emin olun.

Detection

  • Host/sandbox: QEMU'yu ASan altında çalıştırın; özel hazırlanmış uyuşmaz bir request hw/virtio/virtio-crypto.c içinde bir heap-buffer-overflow raporu tetikler.
  • Bir device-model monitor, src_len != dst_len olan virtio-crypto symmetric request'lerini işaretleyebilir; bu bir symmetric cipher için asla meşru değildir.
  • QEMU abort'larını/virtio_error device-broken event'lerini guest crypto aktivitesiyle koreleyin.

Mitigation

  • Patch: 9d38a843 (master) / 49f1e02b (v8.0.4) commit'ini uygulayın; QEMU ≥ 8.1.0'a yükseltin.
  • Attack surface reduction: Gerekli olmadıkça virtio-crypto'yu untrusted guest'lere bağlamayın.
  • Defense in depth: Host tarafı bir overflow'un sınırlanması için QEMU'yu hapsedin (seccomp -sandbox on, SELinux/AppArmor svirt).

References