Skip to content

DRAM bank/row addressing reverse-engineering

Bir physical address'i (channel, rank, bank, row)'a map'leyen dokümante edilmemiş memory-controller fonksiyonlarını yalnızca row-buffer conflict timing'i kullanarak geri çıkar — böylece saldırılar adresleri aynı bank ve komşu row'lara yerleştirebilir.

Mechanism

Same-bank conflict'leri bir timing oracle'dır

Her DRAM bank'ının bir row buffer'ı vardır. Aynı bank'a ama farklı row'lara map'lenen iki adrese erişmek bir row-buffer conflict'ine yol açar: açık olan row kapanır, yenisi activate edilir — bu, farklı bank'lara yapılan iki erişimden (paralel ilerleyen) ya da aynı row'a yapılan erişimden (buffer hit) ölçülebilir şekilde daha yavaştır. DRAMA (Pessl et al.) bu latency farkını bir oracle'a çevirir: birçok adres çiftini ölç, sürekli olarak yavaş olanlar aynı bank'ı paylaşır.

Mapping'in kendisi, physical address bit'leri üzerinde tanımlı bir lineer (XOR) fonksiyon kümesidir. Memory controller; channel, rank, bank-group ve bank'ı seçilmiş adres bit'lerini XOR'layarak seçer, örneğin kavramsal olarak:

bank_bit_0 = a[i] XOR a[j]
bank_bit_1 = a[k] XOR a[l]
channel    = a[m] XOR a[n] XOR ...

Adresleri timing'den yola çıkarak bank'a göre cluster'layabildiğinde, her selector'ı üretmek için hangi bit'lerin birlikte XOR'landığını çözersin — yani fonksiyonları herhangi bir vendor dokümantasyonu olmadan geri çıkarırsın.

Bu mapping; double-sided rowhammer'da aggressor'ları komşu row'lara yerleştirmek, paylaşımlı bellek olmadan cross-CPU covert channel'lar kurmak ve physical bank/row geometrisi üzerine akıl yürütmesi gereken her saldırı için bir önkoşuldur. Altta yatan primitive için row-buffer conflict timing'e bak.

Walkthrough

1. Düşük physical bit'leri bilinen adresleri elde et. Büyük bir bölge allocate et; 2 MB transparent/explicit hugepages physical address'in düşük ~21 bit'ini sabitler, /proc/self/pagemap (okunabilir olduğu yerde) geri kalanı verir.

2. Conflict timing testini kur. Bir (a, b) çiftine, erişimler arasında açık row kapalıyken tekrar tekrar eriş; median latency'yi al:

// alternate a/b, flushing so each access re-activates a row
static uint64_t bank_time(volatile char *a, volatile char *b) {
    uint64_t best = ~0ull;
    for (int i = 0; i < REPS; i++) {
        uint64_t t0 = rdtscp();
        *a; *b;
        uint64_t t  = rdtscp() - t0;
        clflush(a); clflush(b);
        if (t < best) best = t;       // min filters noise
    }
    return best;                      // high => same-bank conflict
}

3. Bank'lara cluster'la. Bir base address seç; adayları tara; base ile eşleştirmesi yavaş olan (conflict threshold'unun üstünde) her aday aynı bank'tadır. Tüm bank'ları enumerate etmek için tekrarla.

Histogram of pair latencies (conceptual)
$ ./drama --measure
latency histogram (cycles):
   ~230  ████████████████  different bank (parallel)
   ~330  ████              same bank, row conflict   <-- threshold here
recovered 16 same-bank clusters (banks x ranks)

Net bir bimodal ayrım, different-bank (hızlı) ile same-bank-conflict (yavaş) durumlarını birbirinden ayırır. Threshold iki mod'un arasında oturur.

4. XOR fonksiyonlarını çöz. Bir bank cluster'ından birçok adres al ve cluster boyunca sabit kalan minimal address-bit XOR kümesini bul; o bit grupları bank/rank/channel selector fonksiyonlarıdır. Geri kalan yüksek bit'ler row index'ini oluşturur.

Hugepages ve pagemap kritik öneme sahip

Large page'ler (ya da physical bit'leri öğrenmenin başka bir yolu) olmadan, timing cluster'larını tekrar adres bit'lerine ilişkilendiremezsin ve fonksiyonlar geri çıkarılamaz hale gelir. Modern kernel'ler unprivileged kullanıcılar için pagemap'i sıfırlar; bu durumda reverse engineering relative/physical-probing yöntemlerine geri düşer.

Prefetcher'lar ve scheduling noise ekler

Prefetcher pattern'ini devre dışı bırak/ondan kaçın, thread'i pin'le ve bir min/median filtre kullan — tek bir non-temporal serseri erişim bir çifti yanlış sınıflandırabilir.

Mitigation

Bu, doğrudan bir fix'i olan bir saldırı değil, saldırıların bağımlı olduğu bir yetenektir: randomize edilmiş address mapping ya da scrambling geri çıkarmanın maliyetini artırır, ama gerçek savunmalar downstream saldırıları hedefler (Rowhammer için TRR/ECC, cross-CPU channel'lar için partitioning).

References