PartitionAlloc double-free to arbitrary allocation¶
Bir PartitionAlloc slot'unu iki kez free et (ya da free iken freelist
next'ini yaz), böylece bucket'ın freelist'i attacker-seçimli bir adrese yönlendirilir ve sonraki aynı-boyutlu bir allocation oraya düşer.
Mechanism¶
Note
Her PartitionAlloc bucket'ı, free slot'ların kendileri boyunca dizilmiş singly-linked bir
freelist'ten aynı-boyutlu slot'lar dağıtır. Allocator'ın güvenliği, canlı bir freelist'in
şu an free olan slot'lardan well-formed, döngüsüz bir zincir olduğu invariant'ına dayanır.
Bir double-free (ya da free edilmiş bir slot'a yapılan bir use-after-free.md
write'ı) o invariant'ı kırar: aynı slot list'te görünür ama aynı zamanda overwrite için
erişilebilirdir, böylece attacker onun encoded next pointer'ını yeniden yazabilir. O
boyuttaki bir sonraki allocation basitçe head'i pop edip next'i takip ettiğinden, next
değerini kontrol etmek lifetime bug'ını bir arbitrary-(kısıtlı)-allocation primitive'ine
dönüştürür — klasik fastbin-dup.md / double-free.md
şeklinin PartitionAlloc'a taşınmış hali, onun encoding ve IsWellFormed check'leriyle
geçitlenmiş.
Walkthrough¶
Kavramsal zincir:
- Bug'ı tetikle / şekillendir. Seçilmiş bir bucket size'ının bir double-free'sini ya da dangling slot'unu elde et, genellikle heap-grooming-feng-shui.md ile grooming sonrasında, böylece victim nesnesi ve attacker-kontrollü nesne bir bucket paylaşır.
- Encoded next'i üzerine yaz. Slot free iken, target'a işaret eden tutarlı bir encoded
next(ve shadow) yaz — bkz. partitionalloc-freelist-pointer-encoding-bypass.md. - Target'a doğru drain et. Head forge edilen entry'ye ulaşana kadar o bucket size'ını
tekrar tekrar allocate et; allocation
targetdöndürür. - R/W kur ya da hijack et. Döndürülen bölgeyi kontrollü bir nesne olarak ele al — tipik olarak arbitrary-read-primitive.md / arbitrary-write-primitive.md için bir length/backing-store field'ını forge etmek, ardından bir function-pointer-overwrite.md.
Warning
PartitionAlloc double-free detection ve same-SuperPage / metadata-avoidance check'leri
ekler, dolayısıyla naif bir double-free abort eder. Çalışan varyantlar free'yi encoding
bypass'ıyla eşler ve target'ı yasal SuperPage bölgesinin içinde tutar, ya da bir thread
cache üzerinden pivot eder
(partitionalloc-threadcache-freelist-corruption.md).
Kararlılığı geri kazanmak
Gerçek exploit'ler, kontrollü allocation'dan sonra freelist'i tekrar makul bir slot'a işaret ettirir, böylece allocator crash etmeden çalışmaya devam eder.
Detection¶
- Instrumented build'lerdeki
FreelistCorruptionDetected()/ double-freePA_CHECKabort'ları doğrudan bir sinyaldir; bu renderer crash imzalarını topla ve triyaj et. - Yeniden kullanılan ya da quarantine'e alınan slot'lar üzerinde ASan/
*Scanişaretleri; SuperPage'lerinin slot bölgesi dışındaki adreslere çözülen allocation'lar.
Mitigation¶
- BackupRefPtr quarantine (backuprefptr-bypass.md) slot reuse'unu
geciktirir;
*Scandangling reference'ları için tarar; MTE-tagged build'ler bayat free'lerde fault eder. - Freelist shadow + double-free check'lerini etkin tut; type/size partitioning attacker nesnesi ile victim'in bir arada bulunmasını engeller.
- Guard page'ler ve metadata confinement, erişilebilir
targetkümesini sınırlar.