CATTmew¶
CATT'in yalnızca-yazılım physical kernel isolation'ını, "double-owned" DMA/mmap kernel buffer'larını Rowhammer'layarak komşu page table'larda bit flip'leyerek yenmek.
Mechanism¶
Teori / invariant
CATT ("CAn't Touch This"), physical domain isolation'a dayalı yalnızca-yazılım bir Rowhammer savunmasıdır: physical memory'yi öyle partition'lar ki her partition tam olarak bir domain'e (user'a karşı kernel) aittir ve partition'ları en az bir kullanılmayan guard DRAM row'u ile ayırır. CATT'in dayandığı invariant, bir aggressor row ile güvenlik açısından kritik bir victim row'un farklı domain'lerde asla hammering mesafesinde oturmamasıdır; böylece kötü niyetli bir user process'in bit flip'leri kernel nesnelerine (örn. page table'lar) ulaşamaz.
CATTmew bu invariant'ı double-owned memory gözlemiyle kırar: modern kernel'ler
aynı anda hem kernel hem user'a ait buffer'lar tutar — kernel partition'ında
allocate edilir (böylece CATT onları kernel nesnelerinin yanına koyar) ama kopyalardan
kaçınmak için privilege'sız bir process'e read/write olarak mmap'lenir. Böyle bir
buffer userspace'ten hammer'lanabilir ve kernel partition'ında yaşar; bu yüzden
bir victim page table (PTE page) ile bitişik yerleştirilebilir. Bir PTE'de bir
bit flip'lemek, user'ın kontrol ettiği bir virtual page'i keyfi bir physical page'e
— başka bir page table dahil — remap'ler ve tam kernel seviyesinde read/write ile root
verir. CATT bu ikilemden kaçamaz: bu buffer'ları user partition'ına taşımak yalnızca
onun yerine driver'ları ve DMA control data'sını açığa çıkarır.
Walkthrough¶
PoC, aggressor olarak iki double-owned buffer türünü hedefler ve victim olarak
page table'ları kullanır. Exploit ne pagemap ne de OOM'a yakın bellek tükenmesi
gerektirir.
Double-owned aggressor buffer'ları (kavramsal)
# Video4Linux2 video buffers (/dev/video0, major 81)
# VIDIOC_REQBUFS -> request memory-mapped buffers
# VIDIOC_QUERYBUF -> get offsets
# mmap() -> map into user space
# up to 32 buffers x 600 KB ~= 18.75 MB hammerable from userspace
# SCSI generic buffers (/dev/sg1)
# SG_SET_RESERVED_SIZE -> raise reserved buffer (default 32 KB -> 124 KB)
# mmap with SG_FLAG_MMAP_IO
# 256 x 124 KB ~= 31 MB; sg yields the larger attack surface
"Memory ambush" (bellek pususu), RAM'i tüketmeden bir aggressor buffer'ı bir victim PTE row'unun yanına yerleştirir:
- Bir tmpfs dosyasını
mmap'leyip page'lerine dokunarak PTE page'lerin lazy allocation'ını zorla (her PTE page 2 MB map'ler). - Dünyaca okunabilir
/proc/buddyinfoüzerinden izlenen tekrarlı 4 KB allocation'larla küçük buddy block'ları boşalt (Phys-Feng-Shui tarzı "önce büyük block'lar" RAM'in ~%99'una ihtiyaç duyar ve çöker; ambush "önce küçük block'lar"ı kullanır). - Double-owned buffer'ı bir DRAM row'una ve PTE page'leri aynı buddy block'un komşu row'una allocate et (row index'i, reverse-engineer edilmiş DRAM map'inden gelen yüksek physical-address bitleriyle ayarlanır — bkz. DRAM bank/row addressing reverse-engineering).
pagemap mevcut olmadığından double-sided hammering imkânsızdır. CATTmew bunun yerine
row-buffer-conflict timing channel aracılığıyla same-bank-different-row (DRSB) adres
çiftleri bulur (bkz.
row-buffer-conflict timing):
# keep only address pairs whose access latency >= 360 cycles
# (clflush + mfence + rdtscp); these are DRSB pairs -> efficient
# single-sided hammering. ~4 min vs ~72 h for naive hammering.
Bir flip sonrası privilege escalation:
- Her map'lenmiş tmpfs page'ini benzersiz bir marker'la işaretle; her hammer round'undan sonra yeniden tara. Marker'ını artık döndürmeyen bir page'in PTE'si remap'lenmiştir.
- Bir entry'yi düzenleyip başka bir mapping'in değiştiğini kontrol ederek remap'lenen page'in kendisinin bir writable PTE page olduğunu doğrula.
- Keyfi physical page'leri map'le -> tüm belleği read/write et; process'in
struct cred'ini tara ve root içinuid'i 0 olarak üzerine yaz.
Tuzaklar
- CVE yok. CATTmew, akademik bir savunmaya artı genel Rowhammer DRAM bug'ına saldırır; bir vendor ürün disclosure'ı değildir.
- PoC yalnızca x86-64 / Linux'tur (Dell Latitude E6420, Lenovo ThinkPad T420, Ubuntu 16.04). ARM/Android ve ION allocator yalnızca ilgili-iş motivasyonu olarak geçer, implemente edilmiş hedefler olarak değil.
- TLB privilege'siz flush'lanamaz: CATTmew değişen PTE'yi belleğe
clflush'lar ve context-switch TLB flush'ını zorlamak için process'i iki çekirdek arasında sektirir.
Detection¶
ANVIL tarzı performance-counter detection, one-location hammering ile ve exploit'i
bir SGX enclave içinde gizleyerek atlatılabilir (perf counter'lar enclave cache
etkinliğini kaydetmez). /proc/buddyinfo ve pagemap'i kısıtlamak saldırıyı yalnızca
hafifçe zorlaştırır.
Mitigation¶
- Yazarların kendi geçici çözümü: CATT'in guard-row fikrini driver buffer'larının kendilerine uygula — her video/sg buffer'ı, her iki yanında birer guard row olan contiguous page'lerden allocate et (buffer başına ~16 KB israf). 500'den fazla mmap'lenmiş kernel buffer'ının hepsine ölçeklenmez.
- Donanım: hedefli/artırılmış DRAM refresh ve TRR (not: TRR daha sonra atlatılabilir gösterildi, örn. TRRespass). SECDED ECC yalnızca single-bit flip'leri düzeltir ve multi-bit flip'lere karşı yetersizdir.
- Kök nedeni ortadan kaldırmak standart Rowhammer ailesi savunmalarını gerektirir; bkz. Rowhammer ve double-sided Rowhammer.