Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-8045 — Exploit for CVE-2025-8045, an Arm Mali GPU kernel driver UAF. Turns a freed GPU buffer into a dirty page table, enabling arbitrary kernel read/write and a root shell on Android. | Kitploit
Tools/GitHubGitHub/kuzeyardabulut/cve-2025-8045
Android SecurityPrivilege EscalationExploitationBinary Exploitation
GitHubkuzeyardabulut/cve-2025-8045

CVE-2025-8045

Exploit for CVE-2025-8045, an Arm Mali GPU kernel driver UAF. Turns a freed GPU buffer into a dirty page table, enabling arbitrary kernel read/write and a root shell on Android.

View Repository
5113 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-8045 — Arm Mali GPU KCPU Queue UAF

A local privilege escalation exploit for CVE-2025-8045, a use-after-free in the Arm Mali GPU kernel driver (kbase). A non-privileged local process races the CSF KCPU queue dump path to free and reclaim a cpu_queue.buffer, turns the dangling allocation into a page table it owns ("dirty pagetable"), and uses that primitive to gain arbitrary kernel physical read/write — ending in a root shell with SELinux set permissive.

Exploited on Pixel 7 Pro (build BP3A.250905.014). The hardcoded offsets in exploit.c are calibrated for this target; other devices/builds need the offsets re-derived (see Tuning & portability).


The vulnerability

CVE-2025-8045 is a use-after-free in the Arm Valhall and 5th Gen GPU Architecture kernel drivers (r53p0–r54p1). A local, unprivileged process can drive GPU processing operations in a way that leaves the driver operating on already-freed memory, opening the door to kernel memory disclosure, corruption, and code execution.

This exploit reaches the bug through the CSF KCPU queue interface exposed by /dev/mali0:

  • A KCPU queue is armed with an unsatisfiable CQS_WAIT followed by a FENCE_SIGNAL. The wait stalls the queue so the fence timer fires later, on a predictable timer-wheel bucket boundary.
  • KBASE_IOCTL_CS_CPU_QUEUE_DUMP drives kbase_csf_cpu_queue_dump_buffer(). Racing the queue's state transition (ISSUED → COMPLETE/PENDING) against the dump path frees cpu_queue.buffer while it is still referenced — the UAF.

The exploit is a timing exploit: it first calibrates the deadline, then predicts it every round and fires a "wave" of harmless dump calls to widen the race window around the moment of the free.

Exploitation strategy

Because one page ends up being both a Mali allocation and a live CPU page table, the process parks forever instead of exiting — freeing it would be a double-free and panic the kernel.

Build

root@kitploit:~
# Android / arm64 (NDK)
aarch64-linux-android31-clang -O2 -o exploit exploit.c

Run

root@kitploit:~
./exploit

On success you get a root shell (uid=0) with SELinux permissive. Sample flow:

root@kitploit:~
[*] pid=...  cpus=8  wave=64  harvest cpu=7  rounds=256
[*] round  1  calibrate  deadline t0+... ms  phase ... ms
[*] round  N  read +... us
[+] UAF page: spray region R page P @ ..., 1 live descriptor
[+] entry 0 = ... -- a CPU page table, writable through the GPU
[+] alias: dirty pagetable
[+] selinux_state.enforcing = 0 @ phys ...
[+] sel_read_enforce patched @ phys ...
[+] root shell: uid=0 euid=0

If it runs all rounds without a win, cpu_queue.c:71 in dmesg indicates the race is landing but the reclaim missed — tune the reclaim/wave parameters.

Tuning & portability

The values in exploit.c are calibrated for the Pixel 7 Pro, build BP3A.250905.014. Offsets and constants are device/kernel-specific and must be re-derived for any other target:

  • KERNEL_PA_BASE, SEL_READ_ENFORCE, INIT_CRED, COMMIT_CREDS, SELINUX_STATE — kernel symbol/physical offsets.
  • ARM64_PTE_FLAGS — last-level descriptor template for the target MMU config.
  • WAVE_*, SWEEP_*, BUCKET_NS, WAIT_NS, spray sizes — race timing and heap-grooming knobs.

Affected versions

  • Arm Valhall GPU Kernel Driver: r53p0 – r54p1
  • Arm 5th Gen GPU Architecture Kernel Driver: r53p0 – r54p1

Update to the fixed driver release from Arm to remediate.

Disclaimer

This code is published strictly for defensive security research, detection engineering, and education. Do not run it against systems you do not own or lack explicit written authorization to test. The author accepts no liability for misuse or for any damage caused. Using it against systems without permission is illegal.

Download Tool
StageWhat happens
CalibrateRound 1 measures the ISSUED→COMPLETE edge to learn the timer-wheel bucket phase.
Predict + sweepLater rounds predict the deadline and sweep the read offset ±ms to land exactly on the free.
Wave64 threads pile CS_CPU_QUEUE_DUMP calls onto csf.lock to bracket the deadline and stretch the window.
ReclaimPre-drain UNMOVABLE free lists, then spray stamped GPU pages so the freed block comes back under our control.
Dirty pagetableFree again and immediately spray CPU page tables into the same page; the GPU allocation now aliases a live last-level table.
Arbitrary R/WA never-reused window PTE is pointed at kernel physical pages; TLB is force-flushed via a PROT_NONE round-trip on a large scratch mapping.
RootClear selinux_state.enforcing, patch sel_read_enforce with commit_creds(init_cred), release a parked child that execs a root shell.