Corrupting memory without memory corruption (CVE-2022-20186)¶
Arm Mali GPU kernel driver'ının alias-memory handling'inde, GPU MMU üzerinden ulaşılabilen doubly-mapped bir physical page üreten bir integer-overflow logic bug'ı — klasik CPU-tarafı memory corruption olmadan bir page use-after-free.
Mechanism¶
Kırılan invariant
Arm Mali GPU kernel driver'ındaki kbase_mem_alias(), bir alias region'ı
destekleyen page sayısını her ikisi de kullanıcı tarafından sağlanan
nents * stride olarak hesaplar. Bir size limiti kontrol edilir ama overflow
check yoktur, dolayısıyla büyük bir stride çarpımı küçük bir page sayısına
wrap'lerken backing region'ları hâlâ mapped kalır. Sonuç, alttaki region'lar
free edildikten sonra GPU-accessible kalan doubly-mapped bir page'tir —
tamamen GPU'nun kendi MMU'su üzerinden ulaşılan bir physical page üzerinde bir
use-after-free. Geçersiz bir CPU pointer'ı dereference
edilmez ve type confusion oluşmaz, dolayısıyla kernel CFI gibi control-flow
savunmaları alakasızdır; sınır, GPU memory-management logic'inin kendisi tarafından
aşılır.
Kavramsal akış (boyutlar/sayılar kernel'e göre değişir; sadece invariant'ı gösterir):
alias size hesabı: count = nents * stride
------------------------------------------------
beklenen: count büyük -> backing region'lar tam adreslenir
gerçek: nents * stride OVERFLOW -> count küçük bir değere wrap'ler
(size limiti check'i geçer, overflow check yok)
GPU MMU mapping'i backing physical pages
+--------------------+ +---------------------+
| alias region (GPU) | ---------> | page P (region A) |
| (count: küçük, | --. +---------------------+
| ama mapping'ler | `------> | page P (yine P!) | <- doubly-mapped
| hâlâ canlı) | +---------------------+
+--------------------+
region A/backing free edildikten SONRA:
+--------------------+ +---------------------+
| alias region (GPU) | ---------> | page P (FREED) | <- UAF:
| hâlâ mapped | | artık başkasına | GPU yazar,
+--------------------+ | reuse edilebilir | allocator
+---------------------+ "free" sanır
Walkthrough¶
GitHub Security Lab advisory'sinden ve writeup'tan çıkarılan kavramsal reprodüksiyon.
- Küçük GPU region'ları allocate et ve
stride'ınents * stride'ı overflow eden bir alias oluştur; örtüşen / doubly-mapped backing page'ler üret. - Alttaki region'ları free et; böylece doubly-mapped physical page hâlâ GPU'ya mapped iken free olur (physical page üzerinde UAF).
- Device'ın shared memory pool'unu manipüle et; böylece bu freed page sonraki verilecek page olsun.
- Yeni GPU page table'larının allocation'ını zorla (çok sayıda page map'le); böylece freed page bir page-table directory (PGD) olarak reuse edilsin.
- Hâlâ geçerli olan GPU mapping'i üzerinden yazarak page-table entry'leri forge et; arbitrary physical read/write elde et.
- Bu physical R/W'yi kullanarak kernel data'sını patch'le / SELinux'u devre dışı bırak ve root'a yüksel — control-flow hijack gerekmez.
Detection¶
- Mali device node'unu (örn.
/dev/mali0) açan ve alias/import ioctl'leri issue eden güvenilmeyen / üçüncü-parti app'ler. - Anormal
kbase_mem_aliasparametreleri: çok büyükstrideya da integer-overflow sınırlarına yakınnents/stridekombinasyonları. - kbase driver tarafından loglanan GPU MMU fault'ları veya page-table tutarsızlıkları.
- Sandbox'lanmış bir app'ten gelen GPU workload'uyla ilişkili, beklenmeyen SELinux permissive geçişi.
- App-sandbox bir UID'den kaynaklanan privilege-escalation göstergeleri (root shell, SELinux devre dışı).
Mitigation¶
- Eksik overflow check'i ekleyen Haziran 2022 Android güvenlik patch'ini / Arm fix'ini uygula (15 Oca 2022 rapor edildi, Arm fix 2 Nis 2022).
- Mali kbase driver'ını sabit bir Bifrost / Valhall sürümünde tut.
- Mümkün olduğunda güvenilmeyen app domain'lerinden GPU device erişimini kısıtla / seccomp-filter'la.
- Control-flow-only savunmaların (kernel CFI) burada yardımcı olmadığına dikkat et; patch'lemeyi artı page-table-integrity korumalarını önceliklendir.
- Driver kodundaki size hesaplamalarına compiler-level integer-overflow sanitization uygula.