Skip to content

udmabuf driver vulnerability (CVE-2023-2008)

udmabuf fault yolundaki eksik bir array-index kontrolü, bir fault index'inin driver'ın pages[] array'inin sonunu aşmasına izin verir ve bir page fault'unu komşu kernel page yapıları üzerinde out-of-bounds erişime çevirir.

Mechanism

udmabuf misc device'ı (drivers/dma-buf/udmabuf.c), userspace'in pin'lenmiş memfd page'lerini DMA-able bir buffer'a sarmasına izin verir. Create yolu (udmabuf_create), kaynak memfd'yi check_memfd_seals() ile doğrular: F_SEAL_SHRINK ister (SEALS_WANTED) ve write seal'lerini reddeder (SEALS_DENIED = F_SEAL_WRITE | F_SEAL_FUTURE_WRITE), böylece backing page'ler udmabuf'ın altından küçültülemez. Driver, backing page'leri oluşturması istenen buffer'a göre boyutlandırılmış internal bir pages[] array'ine kaydeder ve mapping'lenen buffer üzerindeki CPU fault'larını, o array'i fault'layan page offset'i ile indexleyen bir page-fault handler aracılığıyla servis eder.

Note

Burada geçilen güvenlik sınırı bir nesnenin kernel page-table görünümünün memory safety'sidir. Fault handler, fault'layan offset'in (vmf->pgoff'tan türetilen, nihayetinde mapping'in boyutu ve fault adresi üzerinden saldırgan kontrolünde) pages[]'in sınırları içinde kaldığına güveniyordu. Hiçbir doğrulama olmadan (CWE-129, Improper Validation of Array Index), array'in sonunu aşan bir fault, kernel heap'inde array'den sonra duran hangi struct page * ise onu okur ve handler o yabancı page'i saldırganın page table'larına kurar. Kernel'in başka bir yerindeki read-only bir victim page böylece bir userspace VMA'ya writable olarak yeniden mapping'lenebilir — sadece bir crash değil, güçlü bir out-of-bounds primitive'i.

Resmi NVD metni: "The specific flaw exists within a fault handler. The issue results from the lack of proper validation of user-supplied data, which can result in a memory access past the end of an array." Bug, 5.19-rc4'ten önce upstream'de düzeltildi (fix 2022 ortasından beri public'ti; CVE daha sonra, Nisan 2023'te atandı).

Walkthrough

Bu, public olarak belgelenmiş Blue Frost Security analizinin yüksek seviyeli bir yeniden kurgusudur. Offset ya da silahlandırılmış kod tekrar üretilmez.

  1. Device'a ulaş. /dev/udmabuf'ı aç (kvm grubu üyeleri tarafından erişilebilir — misc device'ı sevk eden birçok distro'da, örneğin QEMU için, varsayılan olarak mevcut). Driver'ın create ioctl'i aracılığıyla memfd page'lerini saran bir udmabuf oluştur.
  2. Heap'i groom et. Kernel allocation'larını öyle düzenle ki driver'ın pages[] array'i bir hedef nesnenin hemen öncesine yerleşsin — writeup, backing page'i hijack edilecek read-only page olan bitişik bir pipe buffer kullanır. Bkz. page-spray.md ve heap-grooming teknikleri.
  3. Sınır dışına fault'la. udmabuf'ı mmap() et ve pages[]'in sonunu aşan bir offset'e dokun. Fault handler array'i o out-of-bounds offset ile indexler:

    // conceptual: handler indexes pages[] by faulting offset without a bound check
    struct page *p = ubuf->pages[vmf->pgoff];   // pgoff past nitems -> OOB read
    vmf->page = p;                               // foreign page installed into user PTE
    
  4. Yeniden mapping'le ve overwrite et. Komşu nesnenin read-only page'i artık saldırganın adres alanında writable olarak mapping'lenmiştir. O mapping üzerinden yazmak victim page'i (örneğin pipe buffer içeriğini) değiştirir — privilege escalation'a yönlendirilebilen bir data-only corruption primitive'i. İlgili index/length hataları integer-overflow-wraparound.md ve out-of-bounds-write.md altında görülür.

Warning

İlginç özellik şudur: corruption tamamen page-table remapping ile elde edilir, byte byte bir heap overflow ile değil — klasik slab overwrite'larını gözleyen savunmalar bunu tamamen kaçırabilir.

Note

Mevcut upstream udmabuf.c post-fix sürümdür: page'leri memfd_pin_folios() ile pin'ler ve daha sonra ayrı bir TOCTOU düzeltmesi için check_memfd_seals() çevresinde inode lock'u aldı. Bu CVE'nin esas fix'i (offset/size'ı page array'ine karşı doğrulama) ile o sonraki seal-check hardening'i karıştırma.

Detection

  • Device erişim telemetrisi. /dev/udmabuf'ın virtualizasyon dışı process'ler tarafından, özellikle GPU/DMA işiyle ilgisi olmayan hesaplardan beklenmedik açılışları. EDR, device'a meşru olarak hangi binary'lerin dokunduğunu baseline'layabilir.
  • kvm-grup anomalileri. kvm grubunda hangi local kullanıcıların olduğunu denetle; udmabuf oluşturan virtualizasyon dışı bir kullanıcı şüphelidir.
  • Fault/oops imzaları. Başarısız ya da kısmi exploit denemeleri page-fault oops'ları, BUG: unable to handle kernel paging request ya da dmesg'de udmabuf fault/mmap yollarına atıfta bulunan KASAN out-of-bounds raporları olarak yüzeye çıkar.
  • Davranışsal devamı. Nihai hedef LPE olduğundan, alışılmış post-exploitation belirtilerine dikkat et: beklenmedik uid-0 geçişleri, modprobe_path/core_pattern'a yazmalar ya da unprivileged bir parent tarafından spawn edilen yeni privileged child'lar.

Mitigation

  • Patch. Upstream fix'i içeren bir kernel'e güncelle (mainline ≥ 5.19-rc4, ayrıca Red Hat, SUSE, Ubuntu ve NetApp advisory'lerince takip edilen distro backport'ları). Fix, fault offset'ini buffer'ın page sayısına karşı doğrular.
  • Attack surface'i azalt. Virtualizasyon gerekmiyorsa udmabuf modülünü unload/blacklist et ve misc device'ı kaldır, ya da /dev/udmabuf üzerindeki izinleri sıkılaştır. kvm-grup üyeliğini denetle ve minimize et ki unprivileged kullanıcılar driver'a ulaşamasın.
  • Defense in depth. KASAN (test/CI build'lerinde) OOB read'i kaynağında yakalar; production hardening (CONFIG_INIT_ON_ALLOC, DMA/GPU char device'larına unprivileged erişimi kısıtlama ve STATIC_USERMODEHELPER) data-only escalation zincirini köreltir.

References