PartitionAlloc freelist pointer encoding bypass¶
PartitionAlloc'un encoded/shadowed freelist
nextpointer'larını bertaraf et, böylece transform veIsWellFormedsağlamlık check'lerine rağmen bozulmuş bir free slot yine de attacker-seçimli bir allocation adresi verir.
Mechanism¶
Note
Free bir PartitionAlloc slot'u, singly-linked next pointer'ını düz memory olarak değil,
slot body'sinde saklar. Değer geri çevrilebilir bir transform'dan (little-endian
build'lerde, byte-order ters çevirme / pool-offset encoding) geçirilir ve shadow check etkin
olduğunda, bir shadow field bitwise-ters çevrilmiş encoding'i tutar. Amaç iki yönlüdür:
(a) olduğu gibi dereference edilen encoded bir pointer fault eder ve (b) low byte'ların
partial lineer bir overwrite'ı encoding'i bozar, böylece artık geçerli bir slot'a decode
olmaz ve bunu FreelistEntry::IsWellFormed() reddeder (FreelistCorruptionDetected()).
Attacker'ın bunu bypass etmek için sağlaması gereken invariant bu yüzden rastgele bir
cookie'nin gizliliği değil, iç tutarlılık'tır: encoding pointer'ın deterministik bir
transform'udur (klasik build'lerde per-slot rastgele key yok), dolayısıyla tam encoded
değeri — ve eşleşen bir shadow'u — yazabilen bir attacker, tüm check'leri geçen ve bir
sonraki allocation'ı yönlendiren "well-formed" bir entry üretir.
Walkthrough¶
Kavramsal adımlar:
- Encoding'i geri kazan. Herhangi bir in-slot
nextdeğerini (örn. UAF read üzerinden) leak et ve bilinen transform'u ters çevir — little-endian build'lerde bu byte-swap'tir — böylece plaintext slot adresini, SuperPage base'ini ve offset'leri öğren. - Tutarlı bir entry forge et.
Transform(target)'ı hesapla ve build bir shadow kullanıyorsa, ters çevrilmiş shadow'u da hesapla, böyleceIsWellFormed()kendi-içinde tutarlı bir çift görür. - Sınır içinde kal. Check'ler ayrıca decode edilen next'in aynı SuperPage'de
(thread-cache olmayan list'ler için) ve metadata'da olmamasını gerektirir; bu constraint'leri
sağlayan bir
targetseç, ya da SuperPage sınırlarını aşabilen bir thread-cache list'i üzerinden pivot et. - Yeniden allocate et. Bozulmuş entry bucket'ın freelist'ini besler, böylece sonraki
aynı-boyutlu allocation
targetdöndürür — bkz. partitionalloc-double-free-to-arbitrary-allocation.md.
Warning
Bu, tcache-poisoning.md / freelist-poisoning.md'in PartitionAlloc karşılığıdır: encoding çıtayı yükseltir (full overwrite + shadow + same-SuperPage), ama bu keyed bir MAC değil, obfuscation artı integrity check'leri'dir, dolayısıyla yeterince bilgili bir write geçerli bir entry'yi yeniden inşa eder.
Detection¶
- Bir entry shadow, alignment, metadata ya da same-SuperPage check'lerini geçemediğinde
instrumented/
PA_DCHECKbuild'leriFreelistCorruptionDetected()/IsWellFormed()'de abort eder — uyarı verilmeye değer bir crash imzası. - Non-slot ya da metadata adreslerine decode olan renderer crash'leri ve free edilmiş slot'lar üzerindeki ASan raporları, freelist kurcalamasına işaret eder.
Mitigation¶
PA_CONFIGfreelist shadow check'lerini ve*Scan'i etkin tut; mevcut olduğunda MTE/tagged build'ler gönder, böylece yeniden kullanılan slot'lar fault eder.- Deterministik transform'lar yerine keyed/randomize edilmiş freelist encoding'lerini tercih et ve BackupRefPtr (backuprefptr-bypass.md) quarantine ile birleştir, böylece free edilmiş slot'lar hemen yeniden kullanılabilir olmaz.
- Metadata etrafındaki guard page'ler ve SuperPage-confinement check'leri, forge edilmiş bir pointer'ın nereye işaret edebileceğini sınırlar.