
CVE-2025-21479 proof-of-concept, я думаю
Root-эксплойт для Quest 3/3S для обновления от 7 августа 2025 года и более ранних, основанный на CVE-2025-21479.
скриншот Magisk, Cheese и Termux с root-шеллом
Рутинг опасен. Если вы «окирпичите» Quest 3/3S, восстановить его будет невозможно.
При временном руте это отключает все механизмы безопасности.
НЕ запускайте приложения и не открывайте сайты, которым вы не доверяете.
НЕ записывайте в загрузочный или системный раздел. Вы получите «кирпич».
НЕ используйте функцию «Install» в Magisk.
После получения root вы, возможно, захотите создать резервную копию deviceKey, Meta Access Token и Oculus Access Token.
Вы можете загрузить APK в разделе Release.
См. руководство FreeXR по рутингу Quest 3/3S.
Присоединяйтесь к Discord-серверу FreeXR для получения дополнительной информации.
Более новые версии не поддерживаются. (Старые версии могут быть поддержаны при дополнительной работе.)
Meta исправила CVE-2025-21479 в этих версиях и во всех более новых. Они НИКОГДА не будут поддерживаться.
Этот репозиторий содержит исходный код исполняемого файла командной строки cheese.
Репозиторий cheese-app содержит исходный код приложения.
Это основано на разборах Adreno GPU других исследователей: здесь используется код из:
Дополнительная информация о прошивках Adreno GPU, включая то, как диффить прошивку и как она работает, взята из документации afuc проекта Freedreno от Rob Clark, Connor Abbott и других участников Freedreno/Turnip.
Спасибо разработчикам XRBreak и FreeXR за всю их помощь и вклад.
====
Proof-of-concept для 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 (например, устройства Samsung после майского обновления безопасности 2025) также должны выводить это, но я это не проверял.
# 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
Это запускает командный буфер на GPU Adreno (используя модифицированную версию кода Adrenaline от Project Zero).
Выполняется CP_SET_MODE — это включает немедленное выполнение draw states.
Выполняется 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, что проходит проверку на kernel ring buffer.
Таким образом, вы можете изменить таблицы страниц и вызвать ошибку GPU.
Я диффил несколько прошивок Samsung Galaxy с помощью дизассемблера afuc от Freedreno.
Прошивка Galaxy S24 оказалась самой полезной, поскольку её GPU-прошивка отличается только на одну версию — исправление безопасности:
https://notnow.dev/notice/AuueszvUVUQnWqMQeO
https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE
Прошивка Galaxy S24: gen70900_sqe.fw
https://notnow.dev/notice/Av0a7wUouVSa3EKkE4
Сравнение прошивок Adreno Galaxy S24 между 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 выполняет AND с 0x7 вместо 0x3. Других изменений нет.
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
Он выбирает, какая очередь команд отрисовки будет читаться.
Аппаратное обеспечение Adreno 7xx поддерживает 5 очередей (RB (kernel ringbuffer, привилегированная), IB1, IB2, IB3 или SDS):
https://notnow.dev/notice/Av0kDfOUPKhqHyjyxE
Я думаю, этот дифф и есть CVE-2025-21479. Похоже, это затрагивает только устройства с Adreno A7xx (Snapdragon 8 Gen 1 и выше). Может быть, бюллетень Qualcomm ошибочен?