Load+Reload¶
Load+Reload, AMD'nin L1D cache way predictor'ını suistimal eden bir cache side-channel ölçüm primitive'idir; cache line'larını invalidate etmeden, ancak attacker ile victim'in izlenen adresin physical mapping'ini paylaşmasını (shared memory) gerektirerek, aynı physical core'daki bir victim'in gizli, yüksek doğruluklu memory-access trace'lerini elde eder.
Mechanism¶
Neden çalışır
2011–2019 arası AMD processor'ları, power tüketimini azaltmak için L1 data cache'inde bir way predictor kullanır: tüm cache way'leri boyunca tam bir tag karşılaştırması yapmadan önce, CPU küçük bir predictor yapısına danışarak istenen adresi hangi way'in tuttuğunu tahmin eder ve yalnızca o way'i aktive eder. Predictor state'i her cache access'inde güncellenir ve aynı physical core'daki thread'ler arasında paylaşılır. Victim bir adrese eriştiğinde, o adres için predictor state'i değişir. Aynı core'da çalışan bir attacker, aynı adresi tekrar tekrar load edip bir timing farkı gözlemleyerek bu state değişimini tespit edebilir: bir predictor hit (attacker ve victim aynı predictor entry'sine map'lenen adreslere eriştiler) bir miss'ten ölçülebilir derecede farklı bir latency üretir. Flush+Reload'un aksine, attacker hedef cache line'ı asla flush etmez veya evict etmez; data boyunca cache'te kalır, bu da Load+Reload'u özellikle gizli kılar (victim'in cache performance'ı etkilenmez).
Walkthrough¶
Aşağıdaki, Lipp et al. tarafından "Take A Way"de (AsiaCCS 2020) tanıtılan Load+Reload primitive'ini açıklar:
Adım 1 — Bir baseline kur
Attacker, o adres için baseline predictor latency'sini kurmak amacıyla izlenen adresi tekrar tekrar load eder ve birden çok iteration boyunca timing'i kaydeder.
// Attacker: time repeated loads to the monitored address
uint64_t t0 = rdtsc();
volatile uint8_t v = *(uint8_t *)monitor_addr;
uint64_t baseline = rdtsc() - t0;
Adım 2 — Victim'e yield et
Attacker, victim thread'inin aynı physical core'da çalışmasına izin vermek için anlık olarak CPU zamanını yield eder (veya bir scheduler co-location hilesi kullanır).
// Attacker yields; victim runs on the same physical core
sched_yield(); // or spin-wait for a known victim operation window
Adım 3 — Yeniden ölç
Victim'in çalışma fırsatı bulmasının ardından, attacker aynı adresi yeniden load eder ve timing'i tekrar ölçer.
uint64_t t1 = rdtsc();
volatile uint8_t v2 = *(uint8_t *)monitor_addr;
uint64_t remeasure = rdtsc() - t1;
Adım 4 — Victim erişimini çıkar
baseline ile remeasure arasındaki bir timing farkı, victim'in way predictor'da monitor_addr ile collide eden bir memory adresine eriştiğini gösterir. Attacker, victim'in memory access desenini yeniden inşa etmek için bunu korele eder.
??? Illustrative timing output:
Iteration 1 (no victim access): baseline = 48 cycles
Iteration 2 (victim accessed): remeasure = 61 cycles -> collision detected
Iteration 3 (no victim access): remeasure = 48 cycles -> no collision
Collide+Probe'tan ayırma
Load+Reload, attacker ve victim'in izlenen adresin bir physical mapping'ini paylaşmasını (yani shared memory) gerektirir. Eşlik eden primitive Collide+Probe (aynı paper'dan) shared memory gerektirmez: yalnızca way predictor'daki virtual-address tabanlı collision'lara dayanır, bu da onu tam process isolation sınırları boyunca uygulanabilir kılar. Her iki primitive de aynı "Take A Way" paper'ında açıklanır.
Gizlilik
Hiçbir clflush yayınlanmadığı için, izlenen cache line asla evict edilmez. Alışılmadık eviction oranlarını tespit etmek için tasarlanmış hardware performance-counter tabanlı savunmalar, Load+Reload aktivitesini işaretlemeyebilir.
Detection¶
- Hardware performance counter'ları: Hyperthread'li core'larda anomalous inter-thread desenleri için L1D cache olaylarını ve way-predictor ile ilgili counter'ları (açık olduğu yerde) izle.
- SMT co-residency izleme: Attacker ve victim thread'lerinin aynı physical core'da beklenmedik şekilde birlikte zamanlanmasını tespit et; operating-system düzeyinde CPU affinity ve core partitioning maruziyeti azaltabilir.
- İstatistiksel anomaly detection: Unprivileged bir process tarafından tekrarlanan, ince taneli timing loop'ları kernel düzeyinde izleme agent'ları tarafından işaretlenebilir, ancak benign high-frequency load'ları attack loop'larından ayırmak önemsiz değildir.
Mitigation¶
- Simultaneous multithreading'i (SMT/HyperThreading) devre dışı bırak: Load+Reload, attacker ve victim'in bir physical core'u paylaşmasını gerektirir; SMT'yi devre dışı bırakmak same-core co-residency gereksinimini ortadan kaldırır.
- Core partitioning / CPU pinning: Security-sensitive workload'ları güvenilmeyen process'lerden izole edilmiş özel physical core'larda zamanla.
- AMD microcode / firmware güncellemeleri: AMD, way-predictor araştırmasını kabul etti ve rehberlik yayınladı; predictor tabanlı side channel'ları ele alan belirli microcode güncellemeleri için vendor advisory'lerini kontrol et.
- Way-predictor sertleştirmesi: Gelecekteki microarchitecture tasarımları, way predictor state'ini SMT thread'leri arasında partition edebilir (hyperthreading-aware cache partitioning'e benzer).
- Constant-time programming: Cryptographic kod, data-dependent memory access desenlerinden kaçınmalıdır ki erişimlerin doğru bir trace'i bile secret ile korele hiçbir bilgi açığa çıkarmasın.