Spice / treadm1ll (CVE-2018-4344)¶
"LightSpeed" XNU
lio_listio()race condition'ı —kalloc.16üzerinde bir double-free; tihmstar'ın treadm1ll jailbreak'i bunu iOS 11.4.1'de bir fake Mach port'a ve bir kernel task port'una çevirdi.
Mechanism¶
Note
Bug class: XNU'nun POSIX async-I/O syscall'ı lio_listio()'da, aio_lio_context lifecycle'ının yanlış state yönetiminden kaynaklanan ve bir use-after-free / double-free üreten bir race condition. CVE-2018-4344, LightSpeed lakaplı.
lio_listio(), bir grup async I/O isteğini izlemek için küçük bir aio_lio_context (kalloc.16 zone'undan) allocate eder. Worker thread'leri işleri tamamlandığında context'i free eder. Syscall'daki racy bir path, hiçbir işlem kalmadığına inanırsa context'i aynı zamanda free eder. "Tam olarak bir taraf context'i free eder" invariant'ı zorlanmaz: gönderilmiş iş, syscall'ın kendi check'i çalışmadan önce bir worker thread'inde tamamlanırsa, syscall zaten (veya birazdan) free edilmiş bir object'i free eder — attacker'ın reclaim edebileceği bir dangling kalloc.16 pointer'ı.
Aşılan güvenlik sınırı: free-edilip-reclaim-edilmiş bir kernel object'i, aynı zamanda kalloc.16 boyutunda olan bir out-of-line (OOL) Mach ports array'iyle örtüşecek hâle getirilebilir. Race'i kazanıp slot'u attacker-controlled byte'larla reclaim ederek, attacker içeriğini tamamen kontrol ettiği bir fake Mach port'a receive right elde eder — fake bir kernel-task-port'a ve kernel read/write'a doğru standart pivot.
Warning
treadm1ll, fake-port inşasının parçaları için userland dereference'lerine güvenir, dolayısıyla PAN (Privileged Access Never) zorlanan yerlerde çalışmaz — pre-PAN A7–A9(X) cihazlarını hedefler.
Walkthrough¶
(High-level, tihmstar'ın treadm1ll release'ine ve Project Zero'nun iOS kernel exploit'leri taramasına göre.)
- Trigger thread.
kalloc.16context'ini allocate etmek ve iki kez free etmek için race etmek üzerelio_listio()'yu sıkı bir loop'ta çağır. - Reclaim thread. Bir OOL ports array (yine
kalloc.16) taşıyan bir Mach message'ı tekrar tekrar gönder, ardından hemen — iosurface-property-spray üzerinden — userspace'te crafted bir fake Mach port'a pointer içeren çok sayıdakalloc.16allocation'ı spray et, sonra OOL ports'u receive et. - Race'i kazan. Double-free, OOL ports array slot'unu free eder; spray bunu attacker'ın fake ports array'iyle realloc eder. Message'ı receive etmek, fake port'a bir receive right verir (bkz. fake-mach-port-fakeport).
- Bir adres disclose et. Layout belirsizliğini yenmek için ikinci bir Mach port'u notification port olarak register et ki kernel adresi sızsın.
- R/W kur. Kontrol edilen fake port'u bir kernel read primitive'ine çevir (örn.
pid_for_task()üzerinden), kernel object'lerini bul ve tam kernel read/write için fake bir kernel task port forge et.
Aynı bug, sonraki regression
iOS 12, LightSpeed'i patch'ledi ama root cause'u düzeltmedi ve bir memory leak getirdi; leak'i düzelten iOS 13 değişikliği vulnerable davranışı yeniden ortaya çıkardı — bu regression, tachy0n-unc0ver bug'ıdır (CVE-2020-9859).
Detection¶
- Yoğun threading altında tekrarlı
lio_listio()telemetry'si, Mach message send/receive'e karşı race ederken artı büyükIOSurfaceproperty spray'leri,kalloc.16reclaim girişimlerinin güçlü bir davranışsal imzasıdır. - Zone corruption / panic log'ları. Bir
kalloc.16element'inin double-free'i, freelist corruption ya dazone_require-tarzı panic'ler olarak tezahür eder; bunları untrusted app'lerden gelen iOS panic log'larından topla ve triage et. - Fake-port göstergeleri. Backing belleği beklenen kernel zone'larının dışına çözülen Mach port'ları (post-mitigation
zone_requirecheck'leri), fake-port inşasının kanıtıdır.
Mitigation¶
- Apple'ın patch'i (iOS 12 / CVE-2018-4344).
aio_lio_contextlifecycle'ını düzeltir ki yalnızca bir taraf context'i free etsin; kesin fix daha sonra CVE-2020-9859 patch'i (iOS 13.5.1) üzerinden birio_issued/free_contextaccounting flag'i kullanarak geldi. - kheap separation & zone sequestering (iOS 14+). User-data'yı kernel-object zone'larından ayırmak ve single-purpose zone page'leri kullanmak, bu exploit'in dayandığı cross-type
kalloc.16reclaim'ini kırar. - PAC ve signed
ipc_kmsg. Pointer Authentication ve signed Mach message yapıları, kullanılabilir bir fake port forge etmenin maliyetini artırır. - PAN. Privileged Access Never, treadm1ll'in eski silikonda kullandığı userland-dereference path'ini bloklar.