Skip to content

The code that wasn't there: Reading memory on an Android device by accident (CVE-2022-25664)

Qualcomm Adreno GPU'daki bir cache-coherency açığı, zero-permission bir app'in stale physical page'leri — kernel memory dahil — okumasına ve KASLR'ı bypass etmesine imkân verir.

Mechanism

Note

Aşılan sınır memory safety değil, coherency üzerinden memory confidentiality'dir. ARM64'te kernel, GPU'nun physical memory'den okuduğunun CPU'nun en son yazdığıyla eşleştiğini garanti etmek için cache maintenance'a güvenir. "Yeni map'lenmiş bir page, güncel (sıfırlanmış) CPU tarafından görülebilen içeriği olarak okunur" invariant'ı kırılır, çünkü GPU physical RAM'e doğrudan kendi MMU/IOMMU'su üzerinden, CPU cache'ini bypass ederek erişir.

Bir bölge Adreno GPU'ya map'lendiğinde, backing page'ler "yalnızca CPU cache içinde sıfıra initialize ediliyordu." get_user_pages (IOCTL_KGSL_MAP_USER_MEM) path'inde çağrılan cache-flush hook'ları ARM64'te fiilen no-op'tur: flush_anon_page boştur ve flush_dcache_page cache'i physical memory'ye senkronize etmek yerine sadece page'i deferred flush için dirty olarak işaretler. Yani CPU cache yeni (sıfır) içeriği tutarken physical memory hâlâ önceki sahibin verisini tutar — ve GPU physical, stale versiyonu görür. Free edilen page'ler page allocator içinde döngüye girdiği için bu stale veri "her yerden, başka bir process'ten veya kernel'den gelebilir." Bu, hiçbir memory corruption içermeyen bir information leak / memory disclosure'dır.

Walkthrough

GitHub Security Lab advisory'sine ve Man Yue Mo'nun writeup'ına dayanan yüksek seviyeli bir reprodüksiyon. Parçalar yalnızca açıklama amaçlıdır.

  1. Stale page'lere yönelik bir GPU read kur. Bir page sınırına yakın bir GPU command buffer'ı, bir source bölgesinden num_to_write kelime okuyup bunları attacker'ın okuyabileceği bir destination buffer'a yazan CP_MEM_WRITE-tarzı bir komut yayınlar. Source, physical backing'i hâlâ stale içerik tutan komşu/yeni map'lenmiş bir page'dir.

  2. Sızdırılan byte'ları topla. GPU tamamlandıktan sonra user space destination buffer'ı okur — GPU'nun gözlemlediği her türlü physical içeriği açığa çıkararak. Leak, page granülaritesinde çalışır ve herhangi bir crash veya state corruption olmadan sınırsızca tekrarlanabilir.

  3. Kernel page'lere yönlendir (KASLR bypass). Kernel verisini sızdırmak için yazar page allocator'ı şekillendirdi:

Conceptual KASLR-leak shaping
io_setup() pages (GFP_HIGHUSER) ── reuse freed kernel SLUB pages
free a slab page holding kgsl_syncsource_fence objects
    └─ those objects embed pointers to global kernel structures
GPU-leak the stale page → recover a kernel pointer
    └─ compute KASLR slide from its known symbol offset

Free edilen slab page'ler page allocator'a geri itilir (per-CPU partial list'leri flush ederek), sonra GPU-mappable user allocation'a yeniden verilir; böylece stale read eski kernel slab içeriğine denk gelir.

Bug tesadüfen bulundu ve tamamen informasyoneldir; bu da onu ayrı bir corruption bug'ı ile eşleştirilecek ideal, düşük gürültülü bir info-leak / KASLR-defeat primitive yapar.

Detection

  • GPU ioctl telemetrisi: zero-permission bir app'in, command buffer'ları page sınırlarını aşacak şekilde tekrarlanan IOCTL_KGSL_MAP_USER_MEM + GPU submit döngüleri yayınlaması, özellikle io_setup/GFP_HIGHUSER allocation hareketiyle birlikte.
  • Allocator-pressure sezgileri: per-CPU partial slab list'lerini page allocator'a geri flush etmek için kurgulanmış tekrarlı allocate/free döngüleri, GPU submission'larıyla ilişkili.
  • Düşük gözlemlenebilirlik uyarısı: corruption olmadığı için oops/KASAN sinyali yoktur — detection crash'lere değil, davranışsal GPU kullanım anomalilerine dayanır.
  • Patch durumu izleme: ilgili 2022 patch level'ının altındaki etkilenmiş Adreno cihazlarını işaretle.

Mitigation

  • Patch: Kasım 2021'de raporlandı; Nisan 2022'de özel olarak düzeltildi; Ekim 2022'de kamuya açıklandı. Cache maintenance'ı düzelten Qualcomm/Android security güncellemesini uygula.
  • Root cause fix: GPU'ya map'lenen page'lerin, defer eden veya no-op olan ARM64 flush hook'larına güvenmek yerine, GPU erişiminden önce gerçekten senkronize edilmesini (coherency noktasına kadar cache-cleaned/invalidated) sağla.
  • Hardening / defense-in-depth: untrusted app'ler için GPU device-node erişimini kısıtla; KASLR'ı yenilebilir kabul et ve bir leak'in tek başına code execution vermemesi için CFI, hardened-usercopy ve dedicated-cache mitigation'larıyla birleştir.

References