Skip to content

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.

  1. Küçük GPU region'ları allocate et ve stridenents * stride'ı overflow eden bir alias oluştur; örtüşen / doubly-mapped backing page'ler üret.
  2. Alttaki region'ları free et; böylece doubly-mapped physical page hâlâ GPU'ya mapped iken free olur (physical page üzerinde UAF).
  3. Device'ın shared memory pool'unu manipüle et; böylece bu freed page sonraki verilecek page olsun.
  4. 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.
  5. Hâlâ geçerli olan GPU mapping'i üzerinden yazarak page-table entry'leri forge et; arbitrary physical read/write elde et.
  6. 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_alias parametreleri: çok büyük stride ya da integer-overflow sınırlarına yakın nents/stride kombinasyonları.
  • 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.

References