CVE-2025-21479 概念验证,我认为
适用于 Quest 3/3S 的 Root 漏洞利用(2025 年 8 月 7 日更新及更早版本),基于 CVE-2025-21479。
Magisk、Cheese 和 Termux 带有 root shell 的截图
Root 是危险的。如果你将 Quest 3/3S 变砖,将无法修复。
此操作在临时 root 状态下会禁用所有安全机制。
不要运行你不可信的应用程序或浏览你不可信的网站。
不要写入 boot 或 system 分区。否则你会变砖。
不要使用 Magisk 的“安装”功能。
你可能希望在 root 后备份你的 deviceKey、Meta Access Token 和 Oculus Access Token。
你可以在 Release 部分下载 APK。
加入 FreeXR 的 Discord 以获取更多信息。
不支持更新版本。(旧版本可以通过更多工作获得支持。)
Meta 在这些版本及任何更新版本中修补了 CVE-2025-21479。它们将永远不被支持。
此仓库包含命令行 cheese 可执行文件的源代码。
cheese-app 仓库包含应用的源代码。
基于其他研究人员的 Adreno GPU 写作:此处代码来自:
关于 Adreno GPU 固件的额外信息,包括如何对固件进行差异比较以及固件工作原理,来自 Freedreno 的 afuc 文档,作者为 Rob Clark、Connor Abbott 及其他 Freedreno/Turnip 贡献者。
感谢 XRBreak 和 FreeXR 的开发人员提供的所有帮助与贡献。
====
CVE-2025-21479 的概念验证,证明其仅影响 Adreno A7xx(Snapdragon 8 Gen 1 / XR2 Gen 2 及更新版本)设备。
这仅测试设备是否易受攻击——使其实际产生任何有趣效果需要更多工作。
在未修补的 Adreno A7xx 设备上,运行此程序应输出:
0 0
如果你运行 adb bugreport,在内核 dmesg 中,你将看到:
<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
在 Adreno A6xx 设备上,运行此程序输出:
41414141 42424242
https://notnow.dev/notice/AvIZRBttG7DsDhx9hw
已修补的 Adreno A7xx(例如 2025 年 5 月安全更新后的三星设备)也应输出此内容,但我尚未测试。
# 调整路径指向你的 Android NDK
bash build.sh
adb push cheese /data/local/tmp
adb shell /data/local/tmp/cheese
https://notnow.dev/notice/Av4sfoQjyrxogkZ6Ya
此程序在 Adreno GPU 上运行命令缓冲区(使用 Project Zero 的 Adrenaline 代码的修改版本)
运行 CP_SET_MODE - 这使绘制状态立即运行。
运行 CP_SET_DRAW_STATE - 这会将 IB_LEVEL 设置为 0x4,然后调用指令缓冲区。
在 CP_SET_DRAW_STATE 内部,运行 CP_SMMU_TABLE_UPDATE。
这是固件处理 CP_SMMU_TABLE_UPDATE 的代码:
CP_SMMU_TABLE_UPDATE:
// 获取 IB level
and $02, $12, 0x3
// 如果不是 0(内核环形缓冲区),跳转到 CP_NOP
brne $02, 0x0, #l1873
<实际的 SMMU 修改代码 >
因此,当 IB_LEVEL=4 时,4 与 3 进行与操作得到 0,这就通过了内核环形缓冲区的检查。
因此你可以更改页表,导致 GPU 出错。
我使用 Freedreno 的 afuc 反汇编器对几个三星 Galaxy 固件进行了差异比较。
Galaxy S24 固件帮助最大,因为其 GPU 固件仅相差一个版本——即安全修复版本:
https://notnow.dev/notice/AuueszvUVUQnWqMQeO
https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE
Galaxy S24 固件:gen70900_sqe.fw
https://notnow.dev/notice/Av0a7wUouVSa3EKkE4
对 Galaxy S24 Adreno 固件 v675 和 v676 进行差异比较,显示一种差异类型:
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
每次对 $12 的访问现在都与 0x7 进行与操作,而不是 0x3。没有其他变化。
https://gist.github.com/zhuowei/46a68b9ee53589cdeaa40c11d15d895f
寄存器 $12 似乎是 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
它选择将读取哪个绘制命令队列。 https://gitlab.freedesktop.org/mesa/mesa/-/blob/c0f56fc64cad946d5c4fda509ef3056994c183d9/src/freedreno/afuc/README.rst#id31
Adreno 7xx 硬件支持 5 个队列(RB(内核环形缓冲区,特权级)、IB1、IB2、IB3 或 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
我认为这个差异就是 CVE-2025-21479。 它似乎只影响 Adreno A7xx 设备(Snapdragon 8 Gen 1 及更高版本)。 也许 Qualcomm 公告有误?
我猜测,在 Adreno A7xx 设备上:
CP_SET_DRAW_STATE 执行命令CP_SMMU_TABLE_UPDATE根据 Project Zero 博客文章,CP_INDIRECT_BUFFER 指令调用一个控制处理器指令的间接缓冲区。
当应用程序想要使用 GPU 时,内核的 RB(内核环形缓冲区)将包含一条 CP_INDIRECT_BUFFER 命令,该命令调用用户提供的间接缓冲区 IB1。
此用户缓冲区可以调用自己的间接缓冲区:IB2。
在 A7xx 上,还有 IB3。
此外,在 A6xx 和 A7xx 上,还有 SDS,它不是通过间接缓冲区进入的,而是通过 CP_SET_DRAW_STATE。
https://cs.android.com/android/platform/superproject/+/android15-qpr2-release:external/mesa3d/src/freedreno/decode/cffdec.c;l=3030;drc=0dc791ed57dacf9fe3df694d7f285a8d9f942fa7 https://cs.android.com/android/platform/superproject/+/android15-qpr2-release:external/mesa3d/src/freedreno/decode/cffdec.c;l=2283;drc=0dc791ed57dacf9fe3df694d7f285a8d9f942fa7
A6xx 有 RB、IB1、IB2 和 SDS。
CP_SET_DRAW_STATE 将 IB level 设置为 0x3:在 Galaxy Fold 3 固件的 a650_sqe.fw.v114 中:
mov $03, 0x3
or $12, $12, 0x20
call #fxn1132 // 此处有分支延迟槽,因此暂未执行...
cwrite $03, [$00 + @IB_LEVEL]
但 A7xx 现在有 RB、IB1、IB2、IB3 或 SDS。
CP_SET_DRAW_STATE 现在将 IB level 设置为 0x4:
mov $03, 0x4
cwrite $03, [$00 + @IB_LEVEL]
0x4 & 0x3 = 0x0。
因此,检查当前 IB level 的代码会认为 SDS(设置绘制状态)是 RB(内核环形缓冲区),并且 CP_SMMU_TABLE_UPDATE 等命令将允许执行。