Skip to content

QEMU load_device_tree() heap overflow (deprecated load_image, signed-int path)

QEMU'nun load_device_tree()'sinde bir heap buffer overflow (CVE-2018-20815). Primary root cause, blob'u host buffer'a okuyan rutinin deprecated load_image()'ı kullanmasıdır: load_image() hedef buffer boyutunu almadığı için okuma allocation boyutuna karşı bound'lanmaz ve oversized/hazırlanmış bir DTB host allocation'ı overflow eder. Signed-int üzerinden yapılan device-tree size hesabı ikincil/katkıda bulunan bir faktördür (advisory'nin "could overflow a signed int" ifadesi); başlıktaki "signed-int" buna atıftır.

Mechanism

Note

QEMU, boot anında device_tree.c içindeki load_device_tree() ile guest RAM'e bir flattened device tree (FDT/DTB) yükler. Isolation invariant, QEMU'nun blob'u tutmak için host heap'inde allocate ettiği buffer'ın, ardından içine kopyalanan byte sayısı kadar büyük olması gerektiğidir. Primary root cause, blob'u buffer'a okuyan rutinin deprecated load_image()'ı kullanmasıdır: load_image() çağırana hedef buffer'ın boyutunu bildirme imkânı vermez, dolayısıyla okuma allocation boyutuna karşı hiçbir üst sınırla (bound) sınırlandırılmaz — buffer'a sığandan daha fazla byte kopyalanabilir. İkincil/katkıda bulunan bir faktör, buffer allocate edilmeden önce device-tree size hesabının (fdt_totalsize'dan türetilen değer) bir signed int üzerinden ele alınması ve bu hesabın overflow edebilmesidir (advisory bunu "size manipulation before buffer allocation, which could overflow a signed int" olarak tanımlar). Her iki etki de aynı sonuca varır: rutin, rezerve ettiğinden daha fazla byte kopyalar ve guest/operator-influenced data'yı bir host heap object'inin sonunun ötesine yazar.

Bu, VM kurulumu sırasında bir host-process memory-safety hatasıdır. Corruption QEMU process adres uzayında gerçekleştiği için, guest/operator → host sınırını aşar: DTB'yi (kötü niyetli ya da oversized bir device-tree blob'u) etkileyebilen bir process, QEMU'nun ayrıcalıklarıyla host heap memory'sini bozabilir; bu, host code execution'ın ön koşuludur. Fix, load_image()'ı size-checked load_image_size() ile değiştirir, böylece kopyalama allocation'ı asla aşamaz.

Walkthrough

Public, hâlihazırda patch'lenmiş materyal (Red Hat / openwall advisory'si ve upstream commit da885fe1ee8b4589047484bd7fa05a4905b52b17). Yalnızca kavramsal reproduction path:

  1. load_device_tree(), blob boyutunu belirler ve bu değerden (fdt_totalsize'dan türetilen bir miktar; bu hesap signed int üzerinden yapıldığı için ayrıca overflow edebilir) boyutlandırılmış bir host buffer allocate eder.
  2. Ardından blob'u o buffer'a okumak için deprecated load_image()'ı çağırır. Asıl kusur burada: load_image() çağırana buffer boyutunu bildirme yolu sunmaz, dolayısıyla okumayı allocation boyutuna karşı bir üst sınır olarak zorlamaz — hazırlanmış/oversized bir dosya, allocate edilenden daha fazla byte yazdırabilir.
  3. Kopyalama, allocate edilenden daha fazla byte yazar → device-tree allocation'ına komşu host heap'inde bir out-of-bounds write.

Warning

Tarihsel, patch'lenmiş bir sorun (QEMU 3.1.0). Bu giriş yalnızca bug sınıfını belgeler; hiçbir host heap layout, offset ya da weaponize edilmiş DTB vermez.

Representative fix shape (illustrative)
/* before (vulnerable): unchecked, signed-size load */
fdt = g_malloc0(dt_size);
load_image(filename, fdt);              /* may copy > dt_size */

/* after (fixed, upstream): size-bounded load */
fdt = g_malloc0(dt_size);
if (load_image_size(filename, fdt, dt_size) < 0) { ... }  /* clamped to dt_size */

Exploit olmayan bir denemede beklenen gözlemlenebilir: device tree yüklenirken machine init sırasında QEMU abort'ları / heap-corruption crash'i.

Detection

  • Host tarafı: guest tam ayağa kalkmadan önce, erken machine initialization (device-tree yüklemesi) sırasında QEMU crash'i ya da glibc heap-corruption abort'u.
  • ASan/enstrümante build'ler, load_device_tree() / load_image() içinde bir heap-buffer-overflow write'ı işaretler.
  • Operasyonel olarak: anormal derecede büyük ya da malformed -dtb / device-tree input'ları.

Mitigation

  • CVE-2018-20815 için QEMU fix'ini uygulayın (load_device_tree() içinde size-checked load_image_size() kullanın; commit da885fe1ee8b4589047484bd7fa05a4905b52b17).
  • Untrusted device-tree blob'ları yüklemeyin; -dtb kaynağını ve boyutunu validate edin.
  • Defense-in-depth: QEMU'yu deprivileged/sandbox'lanmış çalıştırın (seccomp, SELinux/sVirt) ki bir host-process overflow'u tam host kontrolü olmasın.

References

  • openwall oss-security, "CVE-2018-20815 QEMU: device_tree: heap buffer overflow while loading device tree blob": https://www.openwall.com/lists/oss-security/2019/03/27/1
  • Red Hat Bugzilla 1693101 (CVE-2018-20815): https://bugzilla.redhat.com/show_bug.cgi?id=1693101