
CVE-2026-20687: AppleJPEGDriver startDecoder Timeout UAF — уязвимость ядра iOS/macOS, приводящая к отложенной панике (A19 Pro, iOS 26.3 RC)
CVE-2026-20687 · Enfilade · enfilade.io
Компонент: Ядро
Воздействие: Приложение может вызвать непредвиденное завершение работы системы или запись в память ядра.
Описание: Проблема использования после освобождения была устранена за счёт улучшенного управления памятью.
| iOS | 26.3 (23D125) (протестировано) |
| macOS | — |
| Компонент | AppleJPEGDriver |
| Исправлено | iOS 26.4 / iPadOS 26.4 |
| Оборудование | iPhone18,2 (iPhone 17 Pro Max, A19 Pro) |
Запуск PoC вызовет kernel panic на устройстве. Сохраните свою работу перед запуском. Повторные паники могут привести к повреждению файловой системы. Только для исследовательских целей в области безопасности.
Путь тайм-аута в startDecoder_sync освобождает запрос, но оставляет указатель на встроенный узел очереди в векторе, привязанном к кодеку. Последующий обход очереди разыменовывает устаревший узел, и ядро паникует при проверке тегов MTE. Паника обычно откладывается до последующего синхронного декодирования JPEG — на iPhone это надёжно происходит при открытии приложения «Камера».
// Инициализирует драйвер; паника обычно откладывается до открытия «Камеры».
IOServiceOpen("AppleJPEGDriver");
for (int i = 0; i < N; i++) {
startDecoder_async(); // queue_io_gated: vector.push(req + 0x78)
}
IOServiceClose(conn);
// Позже открытие «Камеры» запускает:
startDecoder_sync();
queue_io_gated: vector.push(req + 0x78);
wait(10s) -> TIMEOUT;
pool_free(req); // ОШИБКА: не удаляет из очереди (req + 0x78)
// Ещё позже (finish_io_gated):
fullSpeedRequestExist():
node_ptr = vector[i]; // устаревший: node_ptr == (freed req + 0x78)
req2 = *(node_ptr + 0x8); // чтение UAF -> сбой тега MTE -> паника
ios-app/Test.xcodeproj в Xcode.См. LICENSE.