GhostLock: Итоги неудачной эксплуатации на PD2229 (SM8475, 5.10.233 GKI)
1. Сведения об уязвимости и устройстве
1.1 Базовая информация о CVE-2026-43499 (GhostLock)
| Параметр | Значение |
|---|
| Тип уязвимости | Use-After-Free на стеке в пути rt_mutex / futex PI |
| Версия внедрения | Linux 2.6.39-rc1 (май 2011, commit 8161239a8bcc) |
| Версия исправления | Основная ветка 7.1 (commit 3bfdc63936dd), стабильные ветки: 6.1.175 / 6.6.140 / 6.12.86 / 6.18.27 / 7.0.4 |
| Предусловия | CONFIG_FUTEX_PI=y (включено по умолчанию в основных ядрах) |
| CVSS | 7.8 High |
| Стабильность эксплуатации | Оригинальная цепочка NebuSec — 97%, получение root за ~5 секунд |
| Награда kernelCTF | $92,337 USD |
Затронутый диапазон ядер:
- 2.6.39 ≤ Linux < 6.1.175 ✅ Затронуто
- 6.2 ≤ Linux < 6.6.140 ✅ Затронуто
- 6.7 ≤ Linux < 6.12.86 ✅ Затронуто
- 6.13 ≤ Linux < 6.18.27 ✅ Затронуто
- 6.19 ≤ Linux < 7.0.4 ✅ Затронуто
- Android GKI 5.10 отсутствует во всех ветках исправления → 5.10.233 на PD2229 теоретически затронут
1.2 Фактические данные устройства PD2229
2. Идеальная цепочка эксплуатации vs фактический прогресс на PD2229
2.1 Оригинальная цепочка NebuSec (x86_64 / Pixel 10 — успех)
1. Обход KASLR → prefetch timing / PR_SET_MM_MAP auxv
2. Триггер UAF → взаимоблокировка трёх потоков PI → FUTEX_CMP_REQUEUE_PI возвращает -EDEADLK
3. Перехват стека → PR_SET_MM_MAP копирует auxv в стековый фрейм waiter
4. Ограниченная запись rb_erase → перезапись inet6_protos[IPPROTO_UDP]
5. CEA + ROP → перехват потока управления
6. Переключение core_pattern → root shell (97% успеха)
2.2 Фактический прогресс по этапам на PD2229
3. Результаты исчерпывающего поиска примитива перехвата стека (фактические данные PD2229)
3.1 Ключевые вычисления раскладки стековых фреймов
Общая глубина пути futex:
__arm64_sys_futex 0x90
+ do_futex 0xc0
+ futex_wait_requeue_pi 0x1b0
= 0x300
Позиция waiter = SYS_SP - 0x300 + 0x20 = SYS_SP - 0x2e0
Путь pselect:
Стековый фрейм core_sys_select 0x1c0, stack_fds на sp+0x50
Область покрытия: начиная с SYS_SP - 0x1c0 + 0x50 = SYS_SP - 0x170
Расстояние до waiter (SYS_SP - 0x2e0) = 0x170 (368 байт) → перекрытия нет
3.2 Испробованные 17 методов записи в стек
17/17 — все неудачны.
3.3 Корневая причина неудачи
Раскладка стека, созданная компилятором для SM8475 5.10 GKI на PD2229 (PGO + LTO + BOLT), приводит к тому, что stack_fds в core_sys_select и rt_mutex_waiter в futex_wait_requeue_pi архитектурно не перекрываются. Это объективный факт, определяемый компилятором, а не проблема техники эксплуатации.
В репозитории JoinChang прямо указано: "The pselect stack overlay only works when the freed rt_mutex_waiter lands within the user-controllable region of the stack_fds buffer" — PD2229 не удовлетворяет этому условию.
4. Сравнительный анализ публичных репозиториев
NebuSec/CyberMeowfia — оригинальный фреймворк эксплуатации
- Репозиторий: https://github.com/NebuSec/CyberMeowfia
- Цель: x86_64 Linux / Pixel 10 (6.x GKI)
- Перехват стека:
PR_SET_MM_MAP копирует auxv в стек ядра
- Процент успеха: 97%, ~5 секунд до [root shell]
- Применимость к PD2229: ❌
PR_SET_MM_MAP блокируется на Android через EPERM
JoinChang/ghostlock-oneplus — джейлбрейк OnePlus с заблокированным загрузчиком
- Репозиторий: https://github.com/JoinChang/ghostlock-oneplus
- Проверенные устройства:
- OnePlus Ace 6T (PLR110, SM8845) — 6.12.38 GKI ✅
- OnePlus 15 (PLK110, SM8845) — 6.12.23 GKI ✅
- Технические особенности:
- Автоматическое извлечение смещений: kallsyms (28) + BTF (57) + производные (9) + константы (12) = 103/103
- Перекрытие стека pselect, SP diff = -64
PSELECT_SHIFT = -2
- Цепочка эксплуатации: futex UAF → подделка waiter → управление стеком через pselect → ограниченная запись rb_erase → selinux_state.enforcing=0 → перезапись cred на init_cred
- Явное заявление о неприменимости: "Not Feasible (stack layout incompatible)" — применимо только к ядрам, где pselect stack_fds перекрывается с waiter
- Применимость к PD2229: ❌ Поколение ядра не совпадает (6.12 против 5.10), раскладка стека не перекрывается
p2p3p/GhostLock-for-OnePlus — полная эксплуатация OnePlus 6.12
YuKongA/ghostlock-oplus — OPPO Find N5/X8
Адаптация OPPO Find X6 Pro (PGEM10) — 5.15.149
- Устройство: SM8550, 5.15.149-android13, Android 15
- Прогресс: ✅ Обход KASLR (perf_event_open + выборка callchain); последующие этапы не опубликованы полностью
- Значение: Доказывает возможность обхода KASLR на GKI 5.15, но этап перехвата стека публично не подтверждён
pubglite55/oppo-ghostlock — OPPO Find N2
- Репозиторий: https://github.com/pubglite55/oppo-ghostlock
- Устройство: OPPO Find N2 (CPH2413, SM8475)
- Ядро: 5.10.236-android12-9-o-g74d132f4467a
- Android: 16 (BP2A.250605.015)
- Реализовано:
- ✅ Firefox CVE-2026-10702 AAW (этап 1)
- ✅ Обход KASLR (прямое вычисление kaslr_base)
- ✅ Триггер GhostLock FUTEX (FUTEX_CMP_REQUEUE_PI ret=0)
- ✅ Утечка mm_struct через KernelSnitch
- ✅ Хип-спрей sk_buff (4/4 send успешно)
- ✅ Проверка 70+ смещений в IDA Pro
- Основной блокер:
"pselect не может манипулировать структурой waiter — при NFDS >336 fd_set находится в куче; configfs/ashmem не поддерживаются (SET_NAME ashmem усекается); все остальные пути записи в ядро заблокированы (/proc/self/mem, /dev/mem, binder)"
- Связь с PD2229: Та же платформа и поколение (SM8475, 5.10.236 против 5.10.233), разница всего в 3 минорных версии, сталкивается с абсолютно теми же архитектурными ограничениями
harry1080/oppo-ghostlock — OPPO Find N2
- Репозиторий: https://github.com/harry1080/oppo-ghostlock
- Устройство: OPPO Find N2 (CPH2413, SM8475)
- Ядро: 5.10.236-android12-9-o-g74d132f4467a
- Android: 16 (BP2A.250605.015)
- Публичное заявление сообщества:
"pixel10 能利用的版本的 pselect stack_fds 正好和 rt_waiter 在内核栈上重合,这个部分实际上是最麻烦的地方,OPPO findN2 的内核这两个调用的栈部分完全不重合,或者重合也不可控,得找另外的控制栈的方法,要换其他可控内核栈的系统调用来构造栈,简单适配偏移是不可能成功的,oppo 的 rt_waiter 完全与 pselect stack_fds 不重合"
- Связь с PD2229: Как и PD2229, использует SM8475 5.10 GKI, выводы полностью применимы
4.3 Сводная таблица сравнения репозиториев
5. Ключевые символы ядра и смещения (фактические данные vmlinux PD2229)
Статический базовый адрес 0xffffffc008000000, в рантайме необходимо добавить KASLR slide.
Структура rt_mutex_waiter (кастомизация vivo 5.10.233)
struct rt_mutex_waiter {
uint64_t private; // +0x00 (приватное поле vivo)
struct rb_node {
uint64_t rb_parent_color; // +0x08
uint64_t rb_right; // +0x10 (vivo поменял порядок)
uint64_t rb_left; // +0x18
} tree;
struct task_struct *task; // +0x20
struct rt_mutex *lock; // +0x28
};
// Общий размер 0x30 (48 байт)
6. Реализовано vs требуется реализовать
✅ Реализованная инфраструктура
- Обход KASLR —
perf_event_open + выборка callchain (метод аналогичен OPPO Find X6 Pro 5.15.149)
- Триггер UAF — взаимоблокировка трёх потоков PI, FUTEX_CMP_REQUEUE_PI возвращает -EDEADLK
- Полная таблица символов — 103+ символа проверены через IDA (по методологии извлечения 103/103 от JoinChang)
- Раскладка структуры rt_mutex_waiter — кастомные смещения vivo подтверждены
- Точный анализ раскладки стековых фреймов — расчёт глубин путей futex и pselect/io_uring завершён
- Исчерпывающее исключение 17 кандидатов перехвата стека — построена полная матрица «невозможно»
❌ Не реализовано (основной блокер)
- Примитив перехвата стека — раскладка стека компилятора SM8475 5.10 GKI делает его архитектурно недоступным
- Примитив ограниченной записи — невозможно триггернуть rb_erase из-за неудачи перехвата стека
- Все последующие этапы — каскадная блокировка
7. Итоговое заключение
⚠️ GhostLock (CVE-2026-43499) не эксплуатируется на PD2229 (vivo X Fold+, SM8475, 5.10.233 GKI, Android 15 OriginOS 5).
Корневая причина — раскладка стека, созданная компилятором SM8475 5.10 GKI (PGO+LTO+BOLT), из-за которой стековые фреймы всех известных syscall архитектурно не перекрываются с rt_mutex_waiter. Это объективный факт, определяемый компилятором, а не проблема техники эксплуатации.
Все успешные случаи эксплуатации относятся к GKI 6.6/6.12, поскольку вывод компилятора для этих новых ядер обеспечивает идеальное перекрытие pselect fd_set с waiter (SP diff=-64). GKI 5.10 не обладает этим условием.
Созданная инфраструктура
- ✅ Примитив обхода KASLR (побочный канал perf_event_open)
- ✅ 103+ символов ядра и смещений
- ✅ Раскладка структуры rt_mutex_waiter
- ✅ Возможность триггера UAF
- ✅ Матрица исключения 17 кандидатов перехвата стека
9. Индекс репозиториев