Skip to content

The Android kernel mitigations obstacle race (CVE-2022-22057)

Qualcomm kgsl GPU driver'ında bir reference-counting kaynaklı use-after-free; modern Android kernel mitigation'larının tüm engel parkurundan geçirilerek anlatılıyor.

Mechanism

Note

Burada aşılan güvenlik sınırı object lifetime. Qualcomm kgsl driver'ı GPU senkronizasyonunu bir kgsl_timeline object'i ile yönetir; bu object, reference-counted kgsl_timeline_fence (bir dma_fence) object'lerinden oluşan bir list'e (kgsl_timeline::fences) sahiptir. Refcounted bir container'ın korumak zorunda olduğu invariant şudur: reference-counted bir object'e ait bir pointer'ı tuttuğun sürece, ona bir reference de tutmak zorundasın. fences list'i bunu ihlal ediyordu — kgsl_timeline_fence pointer'larını fence refcount'unu artırmadan saklıyordu.

Bir fence oluşturulduğunda (kgsl_ioctl_timeline_fence_get) refcount'u 1 olur. Sahip olan file descriptor kapatıldığında bu sayı sıfıra düşer ve timeline_fence_release çalışarak fence'i free eder — oysa timeline'ın fences list'i hâlâ ona pointer tutmaktadır. &timeline->fences üzerinde yürüyen ikinci bir thread (örneğin kgsl_ioctl_timeline_wait içinde) artık free edilmiş object'i dereference edebilir ve destroy/wait path'leri dma_fence_free üzerinde race eder. Sonuç, yalnızca bir GPU device handle'ı tutan unprivileged bir app'ten erişilebilen klasik bir use-after-free'dir.

Walkthrough

GitHub Security Lab advisory'sine ve Man Yue Mo'nun writeup'ına dayanan yüksek seviyeli bir reprodüksiyon (bkz. References). Parçalar açıklama amaçlıdır, çalışan bir exploit değil.

  1. Race'i kazan / window'u genişlet. Native race oldukça dar. Yazar timeline'a çok sayıda dma_fence object'i ekleyerek lock tutan loop'un daha uzun çalışmasını sağladı, ardından scheduler kontrolü (CPU affinity, SCHED_NORMAL vs SCHED_IDLE) kullanarak preemption'ı yönlendirdi ve free-vs-use sıralamasını güvenilir hale getirdi.

  2. Free edilmiş fence'i reclaim et. Object free edildikten sonra, bir heap spray (sendmsg, signalfd) slot'u yeniden doldurur; böylece dangling list pointer'ı artık attacker'ın şekillendirdiği byte'ları okur ve UAF kontrol edilebilir bir corruption'a dönüşür.

Conceptual race
T1: kgsl_ioctl_timeline_destroy --> dma_fence_put --> refcount 0 --> free(fence)
T2: kgsl_ioctl_timeline_wait    --> walk timeline->fences --> use(fence)  // freed
  1. Sahte bir kernel heap inşa et. Exploit, öngörülebilir adreslenen bir ion memory pool'unu (user_contig_region) kontrollü bir bölge olarak kullandı, ardından double-free / freelist redirection ile kernel allocation'larını buraya yönlendirdi.

  2. KASLR + arbitrary R/W. Bir ion_buffer scatter-gather table'ını corrupt etmek kernel page'lerini tekrar userspace'e map'ledi; bir ion_heap_ops pointer'ını okumak KASLR slide'ını verdi. Buradan yazar arbitrary kernel read/write'a ulaştı, SELinux'u devre dışı bıraktı ve komutları kernel workqueue üzerinden (call_usermodehelper) çalıştırdı.

Writeup'ın asıl konusu bug değil, mitigation'lara karşı verilen aşağıda anlatılan obstacle race'tir.

Detection

  • Cihaz üzerinde GPU driver telemetrisi / EDR: tek bir zero-permission app'ten gelen anormal hacimde kgsl timeline ioctl'ları (*_TIMELINE_FENCE_GET, *_TIMELINE_WAIT, *_TIMELINE_DESTROY), özellikle belirli CPU'lara pinlenmiş thread'ler arasında iç içe geçmiş halde.
  • Crash/oops imzaları: dmesg / bugreport loglarındaki SLUB use-after-free splat'ları, KASAN raporları veya dma_fence refcount uyarıları (refcount_t: underflow) başarısız denemeler sırasında güçlü sinyallerdir.
  • Heap-spray sezgileri: GPU ioctl fırtınalarıyla ilişkili sendmsg/signalfd allocation patlamaları; herhangi bir policy değişikliği olmadan aniden SELinux'un devre dışı kalması.
  • Patch durumu izleme: etkilenen Snapdragon SoC'lerinde Android security patch level'ı Mayıs 2022'den önce olan cihazları işaretle.

Mitigation

  • Patch: Mayıs 2022 Android Security Bulletin / Qualcomm Security Bulletin'inde düzeltildi; ro.build.version.security_patch'in Mayıs 2022 veya sonrası olduğundan emin ol.
  • Root cause fix: fences list'i tuttuğu her kgsl_timeline_fence üzerinde bir reference almalı ve kaldırırken bırakmalı — doğru refcount ownership.
  • Bu araştırmanın yenmek zorunda olduğu (ve çıtayı yükselten) defense in depth katmanları: kernel control-flow integrity (kCFI), stack/heap auto-initialization (CONFIG_INIT_STACK_ALL_ZERO), slab freelist randomization ve hardening, kfree_rcu deferred freeing ve credential'ları/SELinux'u write-protect eden Samsung RKP.
  • Hardening rehberi: mümkün olduğunda GPU device-node erişimini kısıtla; test build'lerinde KASAN'ı etkinleştir; dedicated-cache / cross-cache hardening'i açık tut.

References