Rowhammer.js¶
Privileged
clflushinstruction'ını kullanmadan, yalnızca sıradan memory access'lerle DRAM'i hammer'layan remote, software-induced bir Rowhammer fault attack'i — browser içinde JavaScript'ten çalıştırılabilir.
Mechanism¶
Note
Native Rowhammer, bir aggressor line'ı evict edip bir sonraki read'in DRAM
row'unu yeniden activate etmesi için clflush'a dayanır. clflush,
JavaScript gibi sandboxed/managed ortamlarda kullanılamaz. Rowhammer.js bu
bağımlılığı, eviction'ı yalnızca regular memory access'lerle zorlayarak
ortadan kaldırır: aynı cache set'e map'lenen adreslerden oluşan bir
eviction set kurar ve bunlara CPU'nun complex (non-LRU) replacement
policy'sini yenen bir sırada erişir. Her round aggressor line'ı DRAM'e geri
evict eder, böylece loop herhangi bir flush instruction veya özel privilege
olmadan row'ları yeniden activate etmeye devam eder. Bu, onu ilk remote
software-induced hardware fault attack yapmıştır.
Bu, Rowhammer base bug'ının clflush'sız bir delivery
varyantıdır: aynı charge-leakage mekanizmasını kullanır ama aggressor'ları
flush instruction yerine eviction set'lerle DRAM'e geri iter, böylece sandboxed
JavaScript'ten dahi çalışır.
İşin zor kısmı access pattern: modern Intel LLC replacement basit LRU değildir, bu yüzden congruent set üzerinde naif bir sequential walk target'ı güvenilir şekilde evict etmez. Rowhammer.js, target line'ı regular load'larla güvenilir biçimde dışarı iten eviction strategy'leri türetir, ardından tüm saldırıyı bir browser içinden fully automated olarak sürer.
Walkthrough¶
Eviction tabanlı hammer, native Rowhammer'ın clflush'ını congruent bir
eviction set üzerindeki bir walk ile değiştirir:
// agg_a, agg_b: aggressor addresses (same bank, different rows)
// evset_a, evset_b: addresses congruent with agg_a / agg_b in the LLC
for (;;) {
*(volatile char *)agg_a;
*(volatile char *)agg_b;
for (size_t i = 0; i < EVSET_LEN; i++) // evict agg_a back to DRAM
*(volatile char *)evset_a[i];
for (size_t i = 0; i < EVSET_LEN; i++) // evict agg_b back to DRAM
*(volatile char *)evset_b[i];
}
JavaScript'te aynı fikir büyük bir typed array üzerinde çalışır; aggressor'ları
/proc/self/pagemap olmadan doğru bank'a yerleştirmek için transparent huge
page'ler ve timing tabanlı physical-layout inference kullanılır.
Detection¶
Eviction-set hammering, tek bir thread'den anormal derecede yüksek bir LLC-miss /
DRAM-access rate üretir; performance-counter monitoring bunu flag'leyebilir.
Native hammering'in aksine hiç clflush issue etmez, bu yüzden
flush-instruction tabanlı detector'lar onu kaçırır.
Mitigation¶
Standart Rowhammer hardware defense'leri (artırılmış refresh, TRR, ECC) geçerlidir. Browser seviyesindeki mitigation'lar timer'ların hassasiyetini azalttı ve eviction set kurmaya yardımcı olan API'leri kaldırdı, böylece JS variant'ının maliyetini yükseltti.