Skip to content

zone_require

Bir kernel pointer'ın gerçekten type'ının gerektirdiği zone'a ait olup olmadığını kontrol eden bir XNU mekanizması — type-confused "fake object"leri anında panic'lere dönüştürür.

Mechanism

The invariant

XNU'nun zalloc allocator'ı belirli bir type'ın object'lerini özel zone'larda gruplar (örn. Mach port'ları ipc.ports zone'unda yaşar). zone_require() şu invariant'ı uygular: type T olarak kullanılan bir pointer, gerçekten type-T object'leri tutan zone'dan allocate edilmiştir. Savunduğu security boundary, use time'da type safety'dir: kernel'i, attacker-controlled bir veriyi (diyelim bir kalloc() buffer'ı ya da bir OSData payload'ı) ayrıcalıklı bir kernel object gibi muamele etmeye zorlayabilen bir attacker, membership check'i geçemez; çünkü o veri gerekli zone'da yaşamaz.

Bu, XNU üzerindeki en değerli exploitation primitive'ine doğrudan saldırır: fake ipc_port. Tarihsel olarak bir attacker, Mach port şeklinde, kontrol ettiği bir buffer'ı spray eder ve kernel'i onun üzerinde işlem yapmaya kandırarak fake send right'lar ve arbitrary kernel read/write elde ederdi. zone_require(), hot path'lere (örneğin bir ipc_port lock edildiğinde) bir guard yerleştirir ve port'un backing allocation'ının ipc.ports'ta bulunduğunu assert eder.

Daha geniş XNU memory-safety stack'i ile birlikte çalışır: kheap segregation (KHEAP_DEFAULT vs KHEAP_DATA_BUFFERS), zone sequestering (virtual address'ler free'den sonra bile orijinal zone'larına bağlı kalır) ve kalloc_type (randomized, type-bucket'lı isolation). zone_require runtime assertion'dır; diğerleri ise onun aksi halde yakalayacağı cross-type reuse'u yapısal olarak engeller.

Walkthrough

Üst düzeyde, açık Apple/Project-Zero materyallerinden:

  1. Kernel, bir object pointer üzerinde hassas bir operation'a ulaşır — klasik olarak bir Mach port'unu lock etmek.
  2. Ona güvenmeden önce kod bir membership check çağırır (kavramsal olarak zone_require(ptr, ipc.ports); modern karşılıkları arasında pointer'ın beklenen submap'te yattığını doğrulayan kalloc_non_data_require() / kalloc_data_require() bulunur).
  3. Allocator, ptr'ye sahip olan zone'u zone metadata'sından türetir ve onu beklenen zone ile karşılaştırır.
  4. Mismatch → panic. Bir data buffer içinde forge edilmiş bir fake port, forge edilmiş bir capability vermek yerine anında fail eder.
   ipc_port_lock(port):
       zone_require(port, ipc.ports)   # forged buffer => panic
       ...

Warning

zone_require type confusion'ı daraltır ama yok etmez. Bypass araştırması, gerçek bir same-zone object'i geri kazanmayı (UAF ile yeniden kullanılan gerçek, free edilmiş bir ipc_port check'i geçer) ya da guard'dan yoksun hassas path'ler bulmayı hedefler. Apple'ın bunu yalnızca runtime check'e güvenmek yerine sequestering ve kalloc_type ile eşleştirmesinin nedeni de budur.

Detection

  • On-device: zone_require violation'ları, panic log'unda bir zone-mismatch / zone_require reason string'i ile kernel panic'leri olarak ortaya çıkar — devam eden bir type-confusion exploit'inin yüksek doğrulukta bir göstergesi. Yönetilen filolardan panic log'larını toplayın ve triyaj edin (MDM crash reporting).
  • Anomaly: bir cihazda tekrar eden zone-require panic'leri ya da belirli bir app/userclient ile korele panic'ler, rastgele bir instabilite yerine aktif exploitation girişimlerini düşündürür.

Mitigation

  • Bu zaten bir mitigation'dır; defender'lar için anlamı platformu güncel tutmaktır — zone_require, kheap segregation, zone sequestering ve kalloc_type yalnızca onları içeren OS sürümlerinde koruma sağlar, dolayısıyla zamanında iOS/macOS update'lerini zorunlu kılın.
  • panic-log toplamayı sürdürün ki zone-require fault'ları SOC tarafından görünür olsun.
  • kernel/driver yazarları için: attacker'ın etkilediği tüm allocation'ları data heap/zone'larından geçirin (control structure'ları asla controlled data ile karıştırmayın) ve hassas path'lerde object pointer'lara güvenmeden önce membership check'leri ekleyin.

References