The Android kernel mitigations obstacle race (CVE-2022-22057)¶
Qualcomm
kgslGPU 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.
-
Race'i kazan / window'u genişlet. Native race oldukça dar. Yazar timeline'a çok sayıda
dma_fenceobject'i ekleyerek lock tutan loop'un daha uzun çalışmasını sağladı, ardından scheduler kontrolü (CPU affinity,SCHED_NORMALvsSCHED_IDLE) kullanarak preemption'ı yönlendirdi ve free-vs-use sıralamasını güvenilir hale getirdi. -
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
-
Sahte bir kernel heap inşa et. Exploit, öngörülebilir adreslenen bir
ionmemory 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. -
KASLR + arbitrary R/W. Bir
ion_bufferscatter-gather table'ını corrupt etmek kernel page'lerini tekrar userspace'e map'ledi; birion_heap_opspointer'ı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
kgsltimeline 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ı veyadma_fencerefcount 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/signalfdallocation 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:
fenceslist'i tuttuğu herkgsl_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_rcudeferred 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.