Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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
cheese — CVE-2025-21479 proof-of-concept, I think | Kitploit
Tools/GitHubGitHub/zhuowei/cheese
Android SecurityEmbedded Systems SecurityPrivilege EscalationVulnerability AnalysisExploitationReverse EngineeringMobile SecurityHardware SecurityFirmware AnalysisBinary Exploitation
GitHub
26859681 year agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
zhuowei/cheese

cheese

CVE-2025-21479 proof-of-concept, I think

View Repository

Root exploit for the Quest 3/3S for the August 7, 2025 update and earlier, based on CVE-2025-21479.

screenshot of Magisk, Cheese, and Termux with a root shell

Warning:

  • Rooting is dangerous. If you brick a Quest 3/3S, there is no way to repair it.

  • This disables all security when temp rooted.

  • Do NOT run apps or browse websites you don't trust.

  • Do NOT write to the boot or system partition. You will BRICK.

  • Do NOT use Magisk's "Install" feature.

  • You may want to back up your deviceKey, Meta Access Token and Oculus Access Token after root.

Download

You can download an APK in the Release section.

Guide to root

See FreeXR's guide to rooting the Quest 3/3S.

Join FreeXR's Discord for more information.

Supported versions

  • Quest 3: v79 5115411.12900.520 (August 7, 2025) and below, to about version v71.
  • Quest 3S: v79 117688.9900.610 (August 6, 2025) and below, to about version v71.

No newer versions are supported. (Older versions can be supported with more work.)

Unsupported versions

Meta patched CVE-2025-21479 in these versions and any newer versions. They will NEVER be supported.

  • Quest 3: v79 5115411.13420.520 (August 10, 2025)
  • Quest 3S: v79 117688.10380.610 (August 10, 2025)

Contains code from:

  • adrenaline by Project Zero
  • adreno_user from m-y-mo
  • Freedreno from Mesa
  • shellcode from Longterm Security
  • Magisk from topjohnwu and the Magisk developers.

Source

This repo contains the source for the command line cheese executable.

The cheese-app repo contains the source for the app.

Thanks

This is based on other researchers' Adreno GPU writeups: this uses code from:

  • Project Zero/Ben Hawkes's Adrenaline
  • GitHub Security/Man Yue Mo's adreno_user
  • Freedreno/Rob Clark's kilroy

Additional info on Adreno GPUs' firmware, including how to diff the firmware and how the firmware works, comes from from Freedreno's afuc documentation by Rob Clark, Connor Abbott, and other Freedreno/Turnip contributors.

Thanks to the developers at XRBreak and FreeXR for all their help and contributions.

====

Proof-of-concept for CVE-2025-21479, demonstrating that it only affects Adreno A7xx (Snapdragon 8 Gen 1 / XR2 Gen 2 and newer) devices.

This only tests whether the device is vulnerable - getting this to actually do anything interesting would require more effort.

On unpatched Adreno A7xx devices, running this should print:

0 0

And if you run adb bugreport, in the kernel dmesg, you will see:

<2>[146532.566695][  T933] kgsl kgsl-3d0: GPU PAGE FAULT: addr = 4000031004 pid= 0 name=(null) drawctxt=1111638594 context pid = 0
<2>[146532.566756][  T933] kgsl kgsl-3d0: context=gfx3d_user TTBR0=0x1234567841414141 (write unknown fault)
<2>[146532.566783][  T933] kgsl kgsl-3d0: FAULTING BLOCK: CP

On Adreno A6xx devices, running this prints:

41414141 42424242

https://notnow.dev/notice/AvIZRBttG7DsDhx9hw

Patched Adreno A7xx (e.g. Samsung devices after the 2025 May security update) should also print this, but I have not tested it.

How to use

# adjust path to point to your Android NDK
bash build.sh
adb push cheese /data/local/tmp
adb shell /data/local/tmp/cheese

How it works

https://notnow.dev/notice/Av4sfoQjyrxogkZ6Ya

This runs a command buffer on the Adreno GPU (Using a modified version of Project Zero's Adrenaline code)

Run CP_SET_MODE - this enables draw states to run immediately.

Run CP_SET_DRAW_STATE - this sets IB_LEVEL to 0x4, then calls a instruction buffer.

Inside the CP_SET_DRAW_STATE, run CP_SMMU_TABLE_UPDATE.

Here’s the firmware handling CP_SMMU_TABLE_UPDATE:

CP_SMMU_TABLE_UPDATE:
// get IB level
and $02, $12, 0x3
// if not 0 (kernel ring buffer), go to CP_NOP
brne $02, 0x0, #l1873
<actual SMMU modify code >

So with IB_LEVEL=4, masking 4 with 3 gives you 0, which passes the check for kernel ring buffer.

So you can change the pagetables and causes the GPU to error out.

How I diffed the patch

I diffed several Samsung Galaxy firmwares using Freedreno's afuc disassembler.

The Galaxy S24 firmware was the most helpful, since its GPU firmware only differs by one version - the security fix:

https://notnow.dev/notice/AuueszvUVUQnWqMQeO

https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE

Galaxy S24 firmware: gen70900_sqe.fw

  • April update (S921USQU4BYD9): v675
  • May update (S921USQS4BYE4): v676

https://notnow.dev/notice/Av0a7wUouVSa3EKkE4

Diffing Galaxy S24 Adreno firmware between v675 and v676 shows one type of diff:

        0163: b80300a4  CP_ME_INIT:
        0163: b80300a4  fxn355:
        0163: b80300a4  cread $03, [$00 + 0x0a4]
-       0164: 2a440003  and $04, $12, 0x3
+       0164: 2a440007  and $04, $12, 0x7
        0165: 98641813  ushr $03, $03, $04
        0166: c860004a  brne $03, b0, #l432
        0167: 01000000  nop

Every access to $12 now ANDs with 0x7 instead of 0x3. There are no other changes.

https://gist.github.com/zhuowei/46a68b9ee53589cdeaa40c11d15d895f

Register $12 seems to be the IB level: https://gitlab.freedesktop.org/mesa/mesa/-/blob/c0f56fc64cad946d5c4fda509ef3056994c183d9/src/freedreno/afuc/README.rst#id23 https://gitlab.freedesktop.org/mesa/mesa/-/blob/c0f56fc64cad946d5c4fda509ef3056994c183d9/src/freedreno/afuc/README.rst#id29

Which selects which queue of draw commands will be read. https://gitlab.freedesktop.org/mesa/mesa/-/blob/c0f56fc64cad946d5c4fda509ef3056994c183d9/src/freedreno/afuc/README.rst#id31

The Adreno 7xx hardware supports 5 queues (RB (kernel ringbuffer, priviledged), IB1, IB2, IB3, or SDS): https://cs.android.com/android/platform/superproject/main/+/main:external/mesa3d/src/freedreno/registers/adreno/adreno_control_regs.xml;l=327;drc=c0867f48117dc2c18b1ae689235cb1f60b237600

https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE

I think this diff is CVE-2025-21479. It looks like it only affects Adreno A7xx devices (Snapdragon 8 Gen 1 and above). Maybe the Qualcomm bulletin is wrong?

  • A6xx has 4 IB levels: RB, IB1, IB2, and SDS: SDS=0x3
  • A7xx adds IB3: now there are 5 IB levels: RB, IB1, IB2, IB3, and SDS=0x4.
  • SDS is now 0x4, so masking with 0x3 would give 0x0.

I'm guessing, on an Adreno A7xx device:

  • if you could somehow execute commands at IB level 4 (SDS) with CP_SET_DRAW_STATE
  • and find a command that checks for IB level = RB (kernel-provided ring buffer), such as CP_SMMU_TABLE_UPDATE
  • you can trick it into bypassing the check

Download Tool