
CVE-2025-21479 개념 증명, 제 생각에는
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
루팅은 위험합니다. Quest 3/3S를 벽돌로 만들면 복구 방법이 없습니다.
이것은 임시 루트 상태에서 모든 보안을 비활성화합니다.
신뢰하지 않는 앱을 실행하거나 웹사이트를 탐색하지 마십시오.
부트 파티션 또는 시스템 파티션에 쓰지 마십시오. 벽돌이 됩니다.
Magisk의 "Install" 기능을 사용하지 마십시오.
루트 후에 deviceKey, Meta Access Token 및 Oculus Access Token을 백업하는 것이 좋습니다.
APK는 Release 섹션에서 다운로드할 수 있습니다.
FreeXR의 Quest 3/3S 루팅 가이드를 참조하십시오.
자세한 정보는 FreeXR의 Discord에 가입하십시오.
이보다 새로운 버전은 지원되지 않습니다. (이전 버전은 추가 작업을 통해 지원될 수 있습니다.)
Meta는 이 버전 및 모든 이후 버전에서 CVE-2025-21479를 패치했습니다. 이러한 버전은 절대 지원되지 않습니다.
이 저장소는 명령줄 cheese 실행 파일의 소스를 포함합니다.
cheese-app 저장소에는 앱의 소스가 포함되어 있습니다.
이것은 다른 연구자들의 Adreno GPU 분석 자료를 기반으로 합니다: 다음의 코드를 사용합니다:
Adreno GPU 펌웨어에 대한 추가 정보 (펌웨어 비교 방법 및 펌웨어 작동 방식 포함)는 Rob Clark, Connor Abbott 및 기타 Freedreno/Turnip 기여자들의 Freedreno afuc 문서에서 제공됩니다.
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월 보안 업데이트 이후의 Samsung 기기)도 이 출력을 표시해야 하지만 테스트하지는 않았습니다.
# adjust path to point to your 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:
// 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 >
따라서 IB_LEVEL=4일 때 4를 3으로 마스킹하면 0이 되어 커널 링 버퍼 검사를 통과합니다.
따라서 페이지 테이블을 변경하고 GPU에서 오류를 발생시킬 수 있습니다.
Freedreno의 afuc 디스어셈블러를 사용하여 여러 Samsung Galaxy 펌웨어를 비교했습니다.
Galaxy S24 펌웨어가 가장 유용했습니다. GPU 펌웨어가 보안 수정 하나만 다른 버전이었기 때문입니다:
https://notnow.dev/notice/AuueszvUVUQnWqMQeO
https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE
Galaxy S24 firmware: 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에 대한 모든 접근은 0x3 대신 0x7로 AND 연산을 수행합니다. 다른 변경 사항은 없습니다.
https://gist.github.com/zhuowei/46a68b9ee53589cdeaa40c11d15d895f
레지스터 $12는 IB 레벨인 것으로 보입니다: 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를 사용하여 IB 레벨 4 (SDS)에서 명령을 실행할 수 있다면CP_SMMU_TABLE_UPDATE와 같이 IB 레벨 = RB (커널 제공 링 버퍼)를 확인하는 명령을 찾으면Project Zero 블로그 게시물에 따르면, CP_INDIRECT_BUFFER 명령은 제어 프로세서 명령의 간접 버퍼를 호출합니다.
앱이 GPU를 사용하려면 커널의 RB (커널 링 버퍼)에 사용자가 제공한 간접 버퍼(IB1)를 호출하는 CP_INDIRECT_BUFFER 명령이 포함됩니다.
이 사용자 버퍼는 자체 간접 버퍼(IB2)를 호출할 수 있습니다.
A7xx에는 IB3도 있습니다.
또한 A6xx와 A7xx 모두에는 간접 버퍼가 아닌 CP_SET_DRAW_STATE에 의해 진입하는 SDS가 있습니다.
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 레벨을 0x3으로 설정합니다: a650_sqe.fw.v114 (Galaxy Fold 3 펌웨어)에서:
mov $03, 0x3
or $12, $12, 0x20
call #fxn1132 // there's a branch delay slot, so this isn't executed yet...
cwrite $03, [$00 + @IB_LEVEL]
하지만 A7xx에는 이제 RB, IB1, IB2, IB3 또는 SDS가 있습니다.
CP_SET_DRAW_STATE는 이제 IB 레벨을 0x4로 설정합니다:
mov $03, 0x4
cwrite $03, [$00 + @IB_LEVEL]
0x4 & 0x3 = 0x0.
따라서 현재 IB 레벨을 확인하는 코드는 SDS(설정 드로우 상태)를 RB(커널 링 버퍼)로 간주하여 CP_SMMU_TABLE_UPDATE와 같은 명령이 실행을 허용하게 됩니다.