Adreno A7xx SDS->RB privilege bypass (GPU SMMU takeover to Kernel R/W)
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Bu sayfa, gerçek dünyada bulunan bir Adreno A7xx microcode mantık hatasını (CVE-2025-21479) yeniden üretilebilir istismar tekniklerine soyutlar: Set Draw State (SDS) içindeki IB-seviye maskelemenin suistimal edilerek ayrıcalıklı GPU paketlerinin ayrıcalıksız bir uygulamadan çalıştırılması, GPU SMMU takeover’a geçiş ve ardından dirty-pagetable hilesiyle hızlı, stabil kernel R/W elde edilmesi.
- Etkilenen: Qualcomm Adreno A7xx GPU firmware, register $12 maskesini 0x3’ten 0x7’ye değiştiren microcode düzeltmesinden önceki sürümler.
- Primitive: Kullanıcı tarafından kontrol edilen SDS’den ayrıcalıklı CP paketlerini çalıştırmak (ör. CP_SMMU_TABLE_UPDATE).
- Sonuç: İstediğiniz fiziksel/sanal kernel belleği R/W, SELinux devre dışı, root.
- Önkoşul: KGSL GPU context oluşturabilme ve SDS’ye giren command buffer’ları gönderebilme (normal uygulama yeteneği).
Background: IB levels, SDS and the $12 mask
- Kernel bir ringbuffer tutar (RB=IB0). Userspace, CP_INDIRECT_BUFFER ile IB1 gönderir ve IB2/IB3’e zincirler.
- SDS, CP_SET_DRAW_STATE yoluyla girilen özel bir command stream’dir:
- A6xx: SDS IB3 olarak muamele görür
- A7xx: SDS IB4’e taşındı
- Microcode, geçerli IB seviyesini register $12’de izler ve ayrıcalıklı paketleri ancak etkili seviye IB0 (kernel RB) ile eşleştiğinde kabul ederek filtreler.
- Hata: A7xx microcode, $12’yi 0x7 (3 bit) yerine 0x3 (2 bit) ile masklemeye devam ediyordu. IB4 & 0x3 == 0 olduğundan SDS yanlışlıkla IB0 olarak tanımlandı ve kullanıcı kontrollü SDS’den ayrıcalıklı paketlerin gelmesine izin verildi.
Neden önemli:
A6XX | A7XX
RB & 3 == 0 | RB & 3 == 0
IB1 & 3 == 1 | IB1 & 3 == 1
IB2 & 3 == 2 | IB2 & 3 == 2
IB3 (SDS) & 3 == 3 | IB3 & 3 == 3
| IB4 (SDS) & 3 == 0 <-- misread as IB0 if mask is 0x3
Mikrokod diff örneği (yama maskeyi 0x7 olarak değiştirdi):
@@ CP_SMMU_TABLE_UPDATE
- and $02, $12, 0x3
+ and $02, $12, 0x7
@@ CP_FIXED_STRIDE_DRAW_TABLE
- and $02, $12, 0x3
+ and $02, $12, 0x7
İstismar genel bakışı
Goal: SDS (misread as IB0) üzerinden ayrıcalıklı CP paketleri göndererek GPU SMMU’yu saldırgan tarafından oluşturulmuş pagetable’lara yönlendirmek, ardından GPU copy/write paketlerini kullanarak rastgele fiziksel R/W yapmak. Son olarak, dirty pagetable aracılığıyla hızlı bir CPU-side R/W’ye pivot yapmak.
High-level chain
- Paylaşılan bellekte sahte bir GPU pagetable oluşturun
- SDS’ye girin ve çalıştırın:
- CP_SMMU_TABLE_UPDATE -> sahte pagetable’e geçiş
- CP_MEM_WRITE / CP_MEM_TO_MEM -> yazma/okuma ilkel işlemlerini uygulama
- CP_SET_DRAW_STATE with run-now flags (hemen dispatch)
GPU R/W ilkel işlemleri sahte pagetable aracılığıyla
- Write: CP_MEM_WRITE ile saldırganın seçtiği GPU VA’ya, PTE’lerini seçilen bir PA’ya eşlediğinizde -> rastgele fiziksel yazma
- Read: CP_MEM_TO_MEM hedef PA’dan kullanıcı alanında paylaşılan bir buffera 4/8 bayt kopyalar (daha büyük okumalar için batch)
Notes
- Her Android process bir KGSL context alır (IOCTL_KGSL_GPU_CONTEXT_CREATE). Context geçişleri normalde RB’de SMMU tablolarını günceller; hata sizi SDS’de bunu yapmanıza izin veriyor.
- Aşırı GPU trafiği UI kararmalarına ve yeniden başlatmalara neden olabilir; okumalar küçüktür (4/8B) ve senkronizasyon varsayılan olarak yavaştır.
SDS komut dizisini oluşturma
- Paylaşılan belleğe sahte bir GPU pagetable spray edin, böylece en az bir örnek bilinen bir fiziksel adrese düşsün (ör. allocator grooming ve tekrarla).
- Sırasıyla şu öğeleri içeren bir SDS buffer oluşturun:
- CP_SMMU_TABLE_UPDATE sahte pagetable’in fiziksel adresine
- Yeni çevirilerinizi kullanarak R/W uygulamak için bir veya daha fazla CP_MEM_WRITE ve/veya CP_MEM_TO_MEM paketi
- CP_SET_DRAW_STATE run-now flag’leriyle
Tam paket kodlamaları firmware’e göre değişir; sözcükleri birleştirmek için freedreno’nun afuc/packet dokümanlarını kullanın ve sürücünün SDS gönderim yolunu kullandığından emin olun.
Fiziksel KASLR altında Samsung kernel physbase bulma
Samsung, Snapdragon cihazlarda kernel fiziksel tabanını bilinen bir bölgede rastgeleler. Beklenen aralığı brute-force ile tarayın ve _stext’in ilk 16 baytını arayın.
Representative loop
while (!ctx->kernel.pbase) {
offset += 0x8000;
uint64_t d1 = kernel_physread_u64(ctx, base + offset);
if (d1 != 0xd10203ffd503233f) continue; // first 8 bytes of _stext
uint64_t d2 = kernel_physread_u64(ctx, base + offset + 8);
if (d2 == 0x910083fda9027bfd) { // second 8 bytes of _stext
ctx->kernel.pbase = base + offset - 0x10000;
break;
}
}
physbase bilindiğinde, kernel’in sanal adresini lineer harita ile hesaplayın:
_stext = 0xffffffc008000000 + (Kernel Code & ~0xa8000000)
Hızlı, güvenilir CPU-tarafı kernel R/W’ye stabilize etme (dirty pagetable)
GPU R/W yavaştır ve küçük tanelidir. Kendi işlem PTE’lerinizi bozarak hızlı/kararlı bir primitive’e dönün (“dirty pagetable”):
Adımlar
- Yavaş GPU R/W primitives kullanarak mevcut task_struct -> mm_struct -> mm_struct->pgd öğesini bulun
- İki bitişik userspace sayfası A ve B’yi mmap edin (ör., 0x1000’de)
- A/B’nin PTE fiziksel adreslerini çözümlemek için PGD->PMD->PTE üzerinde gezin (yardımcılar: get_pgd_offset, get_pmd_offset, get_pte_offset)
- B’nin PTE’sini, A/B’yi yöneten son seviye pagetable’a RW öznitelikleriyle işaret edecek şekilde üzerine yazın (phys_to_readwrite_pte)
- B’nin VA’si üzerinden yazarak A’nın PTE’sini hedef PFN’leri eşleyecek şekilde değiştirin; A’nın VA’si üzerinden kernel belleğini oku/yaz, TLB’yi temizleyerek bir sentinel değişene kadar
Örnek dirty-pagetable pivot snippet
```c uint64_t *map = mmap((void*)0x1000, PAGE_SIZE*2, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); uint64_t *page_map = (void*)((uint64_t)map + PAGE_SIZE); page_map[0] = 0x4242424242424242;uint64_t tsk = get_curr_task_struct(ctx); uint64_t mm = kernel_vread_u64(ctx, tsk + OFFSETOF_TASK_STRUCT_MM); uint64_t mm_pgd = kernel_vread_u64(ctx, mm + OFFSETOF_MM_PGD);
uint64_t pgd_off = get_pgd_offset((uint64_t)map); uint64_t phys_pmd = kernel_vread_u64(ctx, mm_pgd + pgd_off) & ~((1<<12)-1); uint64_t pmd_off = get_pmd_offset((uint64_t)map); uint64_t phys_pte = kernel_pread_u64(ctx, phys_pmd + pmd_off) & ~((1<<12)-1); uint64_t pte_off = get_pte_offset((uint64_t)map); uint64_t pte_addr = phys_pte + pte_off; uint64_t new_pte = phys_to_readwrite_pte(pte_addr); kernel_write_u64(ctx, pte_addr + 8, new_pte, false); while (page_map[0] == 0x4242424242424242) flush_tlb();
</details>
## Tespit
- Telemetri: CP_SMMU_TABLE_UPDATE (or similar privileged opcodes) RB/IB0 dışına, özellikle SDS içinde görünüyorsa alarm verin; 4/8-byte CP_MEM_TO_MEM'in anormal patlamalarını ve aşırı TLB flush kalıplarını izleyin
## Etki
GPU erişimi olan yerel bir uygulama ayrıcalıklı GPU paketlerini çalıştırabilir, GPU SMMU'yu ele geçirebilir, keyfi kernel fiziksel/sanal R/W elde edebilir, SELinux'u devre dışı bırakabilir ve etkilenen Snapdragon A7xx cihazlarında (ör. Samsung S23) root alabilir. Ciddiyet: Yüksek (çekirdek ele geçirilmesi).
### Ayrıca bakınız
<a class="content_ref" href="pixel-bigwave-bigo-job-timeout-uaf-kernel-write.md"><span class="content_ref_label">Pixel Bigwave Bigo Job Timeout Uaf Kernel Write</span></a>
## Kaynaklar
- [CVE-2025-21479: Adreno A7xx SDS->RB privilege bypass to kernel R/W (Samsung S23)](https://xploitbengineer.github.io/CVE-2025-21479)
- [Mesa freedreno afuc disassembler README (microcode + packets)](https://gitlab.freedesktop.org/mesa/mesa/-/blob/c0f56fc64cad946d5c4fda509ef3056994c183d9/src/freedreno/afuc/README.rst)
- [Google Project Zero: Attacking Qualcomm Adreno GPU (SMMU takeover via CP packets)](https://googleprojectzero.blogspot.com/2020/09/attacking-qualcomm-adreno-gpu.html)
- [Dirty pagetable (archive)](https://web.archive.org/web/20240425043203/https://yanglingxi1993.github.io/dirty_pagetable/dirty_pagetable.html)
> [!TIP]
> AWS Hacking'i öğrenin ve pratik yapın:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> GCP Hacking'i öğrenin ve pratik yapın: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Azure Hacking'i öğrenin ve pratik yapın: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>HackTricks'i Destekleyin</summary>
>
> - [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
> - **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** bizi **takip edin** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
>
> </details>


