Skip to content

PartitionAlloc cross-bucket overflow

Bir PartitionAlloc bucket'ının slot span'inden komşu memory'ye (komşu bir slot span / farklı-boyutlu bir nesne) geçen lineer bir heap overflow'u kullanarak, size-isolation tasarımının ayrı tutmaya çalıştığı bir nesneyi bozmak.

Mechanism

Note

PartitionAlloc allocation'ları bucket'a (size class) göre ayırır, böylece aynı-boyutlu slot'lar özel slot span'lerde kümelenir ve farklı boyutlar normalde asla birbirine komşu olmaz — açık hedef, lineer bir overflow'un farklı-tipte/boyutlu bir victim'e ulaşamamasıdır ve guard page'ler per-page metadata'ya overflow'u durdurur. Bir cross-bucket overflow, bir out-of-bounds write'ın yine de farklı bir bucket'a ya da slot span'e ait memory'ye ulaştığı durumdur: large/tek-boyutlu bucket'lar SuperPage'lerin içinde ya da arasında komşu biçimde yerleştirilebilir ve yeterince uzun bir OOB write (libwebp huffman_tables overflow'unda olduğu gibi) kendi slot span'inin ötesine, komşu bir allocation'a taşar. Geçilen sınır PartitionAlloc'un size/type isolation invariant'ıdır: write bir kez yabancı bir nesneye düştüğünde, attacker bir field'ı bozar — bir refcount, bir uzunluk ya da geriye kalan tek in-band metadata olan freelist next pointer'ı.

Walkthrough

Kavramsal zincir (kamuya açık libwebp/Blink yazısına göre modellenmiş):

  1. Victim'i komşu yerleştir. Groom et, böylece yararlı bir victim nesnesi overflow eden allocation'ın slot span'ini takip eder (heap-grooming-feng-shui.md, allocation-primitive-shaping.md); bir ThreadPool nesnesini source'un yanına düşürmek için thread-cache draining gerekebilir.
  2. Sınırı aşarak overflow et. OOB write'ı komşuya ulaşacak kadar uzağa sür.
    [ source slot span (bucket A) ][ neighbour (bucket B) ]
             OOB write ───────────────────▶ corrupts B's field
    
  3. Bir pivot field'ı boz. Kamuya açık chain'ler bir ref_count_'u (OOB'yi bir UAF'a dönüştürerek), ya da bir length/backing-store field'ını, ya da free edilmiş bir slot'un freelist pointer'ını bozdu (partitionalloc-freelist-pointer-encoding-bypass.md).
  4. Yükselt. Bozulan nesneyi arbitrary-read-primitive.md / arbitrary-write-primitive.md ve nihai control-flow hijack için kullan.

Warning

Bucket'lar boyutları izole ettiğinden, attacker'lar komşuyu serbestçe seçemez — layout'u erişilebilir komşunun kendisi exploit edilebilir olacak şekilde mühendislik ederler, ya da partitionalloc-double-free-to-arbitrary-allocation.md elde etmek için bir freelist pointer'ına (artık in-band metadata) pivot ederler.

Detection

  • SuperPage/slot-span sınırlarında guard-page fault'ları; faulting write'ı iki allocation'a yayılan renderer crash'leri.
  • Bir source bucket'ı ve farklı-bucket'lı bir victim'i adlandıran ASan/*Scan heap-buffer-overflow raporları; bozulmuş bir freelist entry'si sonradan IsWellFormed()'i geçemediğinde integrity abort'ları.

Mitigation

  • Per-size/type partitioning + guard page'ler birincil savunmadır; slot-span padding'i tut ve cross-slot write'lar fault etsin diye MTE-tagged build'ler gönder.
  • BackupRefPtr (backuprefptr-bypass.md) OOB→UAF pivot'unu körleştirir; bounds-check'li container'lar ve kök OOB'yi düzeltmek primitive'i ortadan kaldırır.
  • *Scan ve freelist shadow check'leri alt katmandaki freelist corruption'ını yakalar.

References