Skip to content

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:

  1. 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.
  2. 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.
    free(slot); ... ; *(slot as freelist_entry).next = Transform(target)
    
  3. Target'a doğru drain et. Head forge edilen entry'ye ulaşana kadar o bucket size'ını tekrar tekrar allocate et; allocation target döndürür.
  4. 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-free PA_CHECK abort'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/*Scan işaretleri; SuperPage'lerinin slot bölgesi dışındaki adreslere çözülen allocation'lar.

Mitigation

  • BackupRefPtr quarantine (backuprefptr-bypass.md) slot reuse'unu geciktirir; *Scan dangling 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 target kümesini sınırlar.

References