kheap segregation (KHEAP_DATA_BUFFERS / KHEAP_DEFAULT / KHEAP_KEXT / KHEAP_TEMP)¶
XNU, kernel heap'i ayrı namespace'lere böler, böylece saldırgan-kontrollü data buffer'ları kernel object'leriyle asla virtual address space paylaşamaz; bu da cross-type heap grooming'i ve UAF reallocation'ını yener.
Mechanism¶
Güvenlik invariant'ı
kheap segregation bir data/control ayrımı invariant'ı zorunlu kılar: saf, saldırgan-etkili byte'lar tutan bir allocation'ın (bir KHEAP_DATA_BUFFERS allocation'ı), daha önce pointer'lar, reference count'lar ya da type tag'leri içeren bir kernel control object'i tutmuş — ya da daha sonra tutabilecek — aynı virtual address aralığını işgal etmesine asla izin verilmemelidir. Tek kernel heap'ini ayrı namespace'lere bölerek XNU, klasik exploitation deseninin evrensel önkoşulunu ortadan kaldırır: belleğin bir bölgesini iki çelişen type olarak yorumlanmaya zorlamak.
Bunun çıtayı yükseltme nedeni şudur: çoğu kernel memory-corruption exploit'i bir değeri doğrudan corrupt etmez; bir type confusion mühendisliği yapar. Bir use-after-free, free edilmiş object A'ya bir referansı dangle eder, saldırgan A'nın belleğini farklı bir type'taki object B ile geri alır ve A'da bir length olan field artık B'de bir pointer olur (ya da tersi). O reclamation adımı, free edilmiş belleğin arbitrary bir type tarafından yeniden kullanılabilir olmasına bağlıdır. Segregation, en kontrol edilebilir reallocation primitive'inin — içeriğini saldırganın byte-byte seçtiği ham bir data buffer'ı — kendi namespace'inde yaşamasını ve asla bir control object'in üzerine düşememesini sağlayarak bu adımı kırar.
Walkthrough¶
XNU, her biri kendi kalloc zone ailesiyle desteklenen birkaç kheap namespace'i tanımlar:
KHEAP_DEFAULT— control structure'ları tutan genel amaçlı kernel heap: pointer'lar, count'lar ve type metadata içeren object'ler.KHEAP_DATA_BUFFERS— içeriği saf byte olan ya da doğrudan userspace'ten kontrol edilen allocation'lar (copy-in edilmiş buffer'lar, string data'sı, ham byte array'leri). Bu, saldırganın en esnek reallocation aracını izole eden namespace'tir.KHEAP_KEXT— (erken tasarımlar, iOS 14) kernel-extension allocation'larını çekirdek kernel heap'inden ayırdı. Type tabanlıkalloc_typeşeması faydasını kapsadığı için sonradan geri katlandı.KHEAP_TEMP— (erken tasarımlar) kısa ömürlü allocation'ların onları oluşturan syscall'dan daha uzun yaşamamasını zorunlu kılmayı amaçlıyordu; karmaşıklığa kıyasla yetersiz güvenlik değeri sağladığı için sonradan kaldırıldı.
İki tamamlayıcı özellik bölmeyi etkili kılar:
- Zone sequestering / virtual-address yeniden kullanmama. Bir virtual page bir zone'a ait olduktan sonra, o VA aralığı başka bir type tarafından arbitrary yeniden kullanım için global bir pool'a geri verilmez. Free-ama-boş chunk'lar VA atamalarını korur, yani bir saldırgan bir control object'i free edip onun tam adresini bir data buffer ile geri alamaz.
- Azaltılmış reallocation adayları. Saf-data buffer'larını object heap'inden çıkarmak, en generic "her şeyi spray et" reallocation object'ini ortadan kaldırır, yani saldırganın confusion için de işe yarayan aynı-namespace, aynı-size-class bir object bulması gerekir.
kalloc_type ve pointer-array isolation ile ilişkisi
kheap segregation kaba ilk katmandır. Onun üzerine kalloc_type, her size class içinde type tabanlı segregation ekler: compiler type başına bir "signature" yayar (hangi 8-byte granule'lerin pointer mı yoksa data mı olduğu) ve erken boot signature'ları sabit bir kalloc.type* zone setine dağıtır, böylece belirli bir type yalnızca kendi zone'unu paylaşan type'lar tarafından geri alınabilir. Ayrıca, pointer array'leri (örn. out-of-line Mach port array'leri) — tarihsel olarak gözde bir generic reallocation object'i — kendi heap'lerine izole edilir. Bkz. kalloc-type.md.
Üst düzey bypass sınıfları (public olarak belgelenmiş)
kalloc_type'ta signature collision'ları: işlevsel olarak farklı ama özdeş pointer/data layout'una sahip type'lar (C++ inheritance'ta yaygın) aynı bucket'a çöker ve küçük bir confusion adayı kümesi bırakır.- Data olarak typed pointer'lar: semantik olarak bir kernel pointer'ı tutan ama
uint64_tolarak tanımlanmış bir field, annotate edilmedikçe deterministik bir pointer/data overlap'i oluşturur. - Data-submap içi corruption: bir pointer field'ını tamamen data submap içinde kontrol etmeye yönlendirilebilen bir UAF, object-heap segregation'ıyla hiç uğraşmak zorunda kalmayabilir.
- Info-leak destekli ön hesaplama: bir leak ile saldırgan, uygulanabilir aynı-zone değiştirme type'larını önceden enumerate edip runtime'da birini seçebilir ve boot başına randomization'ı kısmen dengeleyebilir.
Detection¶
- Bir araştırma/debug build'inde, data ve typed zone'ların ayrı olduğunu doğrulamak için zone metadata'sını incele (örn.
zprint, ya da bir kernel debugger'dakalloc.data*/kalloc.type*zone isimleri). - Kernelcache analiz araçları, zone table'larını ve
kalloc_typeview/zone bağlamalarını enumerate edebilir ve segregation'ın belirli bir XNU build'i için compile edildiğini doğrulayabilir. - Anomali sinyali: bir corruption zone sınırlarını geçmeye çalıştığında raise edilen allocator panic'leri ya da zone-element-corruption panic'leri, segregation/sequestering'in aktif olduğunun dolaylı bir göstergesidir.
Mitigation¶
- XNU'yu güncel tut: segregation,
kalloc_typeve pointer-array isolation sürümler boyunca evrildi; eski tasarımların (KHEAP_KEXT,KHEAP_TEMP) yerini daha güçlü type tabanlı şemalar aldı. - Driver/kext yazarları için: ham, dışarıdan-kontrollü byte buffer'larını data namespace'i üzerinden yönlendir ve onları pointer içeren structure'larla asla karıştırma; semantik olarak kernel pointer'ı tutan field'ları annotate et ki type signature'ı doğru olsun.
- Segregation'ı defense-in-depth'te bir katman olarak ele al —
read-only-after-init.md,strict-kernel-rwx.md, hardware kernel-text koruması (ktrr.md) ve PAC (arm-pointer-authentication.md) ile birleştir. En yeni silikonda, tag tabanlı memory safety (memory-integrity-enforcement-enhanced-mte.md) cross-allocation confusion'ını daha da kısıtlayan spatial/temporal kontroller ekler.