Skip to content

CVE-2022-20122: PowerVR GPU driver pinned-memory unpin/free memory corruption (Android)

Unprivileged bir app, GPU için bir memory allocation'ı pin'ler, sonra unpin edip kernel'in backing page'leri serbest bırakmasına olanak tanır, ama driver bayatlamış GPU mapping'ini canlı tutar — sonraki GPU erişimlerini kernel-managed memory'ye karşı bir use-after-free'ye çevirir.

Mechanism

Imagination DDK'da pin/unpin lifetime uyuşmazlığı

Imagination'ın PowerVR DDK'sı, GPU memory'yi bir Physical Memory Resource (PMR) soyutlaması üzerinden sunar. User space bir PMR allocate eder, sonra kernel'den backing page'leri pin'lemesini ister, böylece GPU onları referans ederken migrate edilemez veya reclaim edilemez. Pinning, bir page'in GPU'nun MMU'suna kararlı bir physical hedef olarak verilmeye uygun hale gelmesini sağlayan şeydir.

Tasarımın dayandığı invariant basit: bir page yalnızca pin'liyken canlı bir GPU mapping tarafından referans edilebilir. GPU mapping'inin lifetime'ı, pin'in lifetime'ının bir alt kümesi olmak zorunda.

CVE-2022-20122 bu invariant'ı bozar. Bridge yüzeyi, unprivileged bir process'in şunu yapmasına izin verir:

  1. Bir PMR allocate eder ve page'lerini pin'ler.
  2. Aynı PMR'ı unpin eder — bu da kernel'e page'lerin artık kullanımda olmadığını ve OS page allocator tarafından reclaim/free edilebileceğini söyler.
  3. O page'ler için (artık bayatlamış) mapping'i hâlâ referans eden GPU operasyonlarını issue etmeye devam eder.

Driver, GPU-side reference'ını unpin'e karşı invalidate etmediği veya refcount'lamadığı için, GPU MMU hâlâ onlara işaret ederken physical page'ler free edilip kernel tarafından alakasız bir allocation için geri dönüştürülebilir. GPU — translation bir kez var olduğunda physical RAM'in geri kalanından MMU-enforced bir izolasyonu olmayan, tamamen DMA-capable bir bus master — sonra artık sahip olmadığı page'leri okur ve yazar. Bu klasik bir use-after-free (CWE-416) ve free edilen page'ler keyfi kernel object'leri olarak reclaim edilebildiği için kernel memory corruption'a escalate eder.

İki özellik bunu ciddi yapar:

  • Hiç privilege gerekmez. GPU device node'larına sıradan app'ler ulaşabilir (GPU paylaşımlı compute/graphics donanımıdır), yani attack surface tüm güvenilmeyen application sandbox'ıdır.
  • GPU write engine'idir. CPU asla CAP_SYS_ADMIN'e veya kendi kernel write primitive'ine ihtiyaç duymaz; yazma işini yapması için GPU'yu sürer, CPU-side memory protection'larını atlar.

Bu, daha önceki CVE-2021-39815 pin/unpin sorunuyla aynı sınıftan bir bug — PMR pin path'inde tekrar eden, ikinci bir fix gerektiren bir lifetime-handling zayıflığı.

Walkthrough

Bug, PowerVR bridge (/dev/pvr_sync / PVRSRVBridge ioctl multiplexer'ı) üzerinden erişilebilen kernel GPU driver'ında yaşar. Kavramsal saldırı dizisi — tamamen unprivileged bir Android app'inin UID'inden yürütülür — şudur:

Kavramsal exploitation akışı (gösterim amaçlı, çalışan bir PoC değil)
/* 1. Open the GPU device exposed to unprivileged apps. */
int fd = open("/dev/pvr_sync", O_RDWR);   /* PowerVR bridge endpoint */

/* 2. Allocate a PMR (physical memory resource) and obtain its handle. */
PMR_HANDLE pmr = PhysmemNewRamBackedPMR(fd, /* size, flags ... */);

/* 3. Pin the PMR so its pages become a valid GPU mapping target. */
DevmemIntPin(fd, pmr);          /* pages are now pinned for the GPU */

/* 4. Map the pinned pages into the GPU virtual address space. */
gpu_va = DevmemIntMapPMR(fd, pmr, /* ... */);

/* 5. Unpin: tells the kernel the pages may be reclaimed/freed,
 *    BUT the GPU mapping (gpu_va) is left intact. */
DevmemIntUnpin(fd, pmr);        /* <-- pages now reclaimable by the OS */

/* 6. Force the freed pages to be reused for a target kernel object,
 *    e.g. by pressuring the page allocator. */

/* 7. Submit GPU work that reads/writes through the stale gpu_va.
 *    The GPU now touches memory that has been recycled into a
 *    different kernel allocation -> controlled corruption. */
submit_gpu_kick(fd, gpu_va, /* attacker-chosen data */);

Yukarıdaki tam bridge fonksiyon isimleri PMR pin/map akışının gösterimi amaçlıdır; advisory tarafından doğrulanan yük taşıyan gerçek, patched driver'ın reddettiği "pin → map → unpin → mapping'i kullanmaya devam et" mantıksal dizisidir.

Patched bir cihazda beklenen davranış: unpin path'i ya hâlâ canlı GPU mapping'leri olan page'leri serbest bırakmayı reddeder ya da o mapping'leri yıkar/invalidate eder, böylece 7. adım memory'yi bozmak yerine fault verir veya bir hata döner.

Vulnerable bir cihazda 7. adım geri dönüştürülmüş page'lere karşı başarılı olur ve attacker'a, hedefi free edilen page frame'ini yeniden kullanan hangi kernel object ise o olan bir write primitive verir.

Triage için advisory metadata:

CVE:        CVE-2022-20122
Component:  Imagination Technologies PowerVR-GPU (Android)
Android ID: A-232441339   (binary driver, not in AOSP source)
Severity:   High (Android bulletin)  /  CVSS 3.1 9.8 Critical (NVD)
Vector:     CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE:        CWE-416 Use After Free
Patched:    Android Security Bulletin 2022-08-01

CVSS AV:N hakkında

NVD ve GitHub Advisory'nin yayımladığı vektör AV:N (network) taşır, oysa trigger pratikte yerel bir GPU device node'u (/dev/pvr_sync) üzerinden, cihazda çalışan unprivileged bir app'ten gelir. Bu, gerçek bir uzaktan-network erişim gereksinimi değil; Android driver CVE'lerinde sık görülen, advisory'nin published scoring'ine sadık kalan bir tutarsızlıktır. Saldırı yüzeyi yine de "cihaz üzerindeki herhangi bir untrusted app" kadar geniştir (PR:N), ki bu da 9.8 Critical skorunu açıklar. Vektör yukarıda NVD'de yayımlandığı gibi (doğrulandı) bırakılmıştır.

Detection

  • Patch level. Cihazın security patch level'ının 2022-08-01 veya sonrası olduğunu doğrula; Pixel cihazlarında fix, Google'ın developer sitesindeki güncellenmiş binary GPU driver'ında geldi. Fix, AOSP'de değil closed-source vendor blob'unda olduğundan bir source diff mevcut değil.
  • Behavioral. Bir PMR'ı pin'leyen, unpin eden ve sonra aynı allocation'ı referans eden GPU işini submit etmeye devam eden bir app için audit yapmak güçlü bir sinyal, ama genellikle yalnızca vendor'a açık olan GPU-driver-level tracing gerektirir.

Mitigation

  • Ağustos 2022 Android security update'ini / güncellenmiş PowerVR DDK'sını uygula.
  • GPU driver tarafında fix, lifetime invariant'ını zorlar: bekleyen GPU mapping'leri olan bir PMR, o mapping'ler geçerli kaldığı sürece unpin-edilip-sonra-free edilemez.
  • Defense in depth: threat model'in izin verdiği yerde hangi app UID'lerinin GPU device node'larına ulaşabileceğini kısıtla (GPU erişiminin geniş olduğu Android'de sınırlı).

References