Skip to content

BranchScope (directional predictor attack)

Bir victim conditional branch'in taken/not-taken yönünü, paylaşılan directional branch predictor (PHT) içinde onunla collision'a girerek infer et ve secret'a bağlı control flow'u geri kazan.

Mechanism

Note

Bir branch predictor iki parçadan oluşur: bir indirect branch'in nereye gittiğini tahmin eden Branch Target Buffer (BTB) ve bir conditional branch'in taken olup olmadığını tahmin eden directional predictor — tipik olarak 2-bit saturating counter'lardan oluşan bir Pattern History Table (PHT). Daha eski branch side channel'lar (örn. Jump-over-ASLR) BTB'yi hedef alıyordu; BranchScope ise directional predictor'a yönelik ilk ince taneli (fine-grained) attack. Değişmez nokta şu: PHT entry'leri sibling logical core'lar / context'ler arasında paylaşılır ve branch adresine (ve history'ye) göre indexlenir. Eğer attacker'ın branch'i bir victim conditional branch ile aynı PHT entry'sine map'leniyorsa, victim'in taken/not-taken sonucu paylaşılan counter'ı belli bir yöne çeker. Attacker önce counter'ı bilinen bir state'e zorlar, victim'in secret branch'i çalıştırmasına izin verir, sonra kendi branch'inin artık taken olarak mı tahmin edildiğini (misprediction timing üzerinden) ölçer; böylece victim'in branch yönünü — ve dolayısıyla o branch'i süren bir secret bit'i — okur.

Walkthrough

Attacker ve victim directional predictor'ı paylaşır (örn. SMT sibling'lar ya da tek bir core üzerinde time-sliced) ve attacker bir PHT collision'ı bilir/zorlar.

  1. PHT entry'sini prime'la: sabit yönlü, colliding bir branch'i tekrar tekrar çalıştırarak counter'ı bilinen bir state'e getir.

  2. Victim'i bir kez çalıştır: secret'a bağlı conditional branch bir defa koşar; sonucu paylaşılan 2-bit counter'ı iter.

  3. Probe et: attacker branch'ini çalıştır ve doğru tahmin edilip edilmediğini ölç — bir misprediction, victim'in counter'ı nasıl hareket ettirdiğini açığa çıkarır:

// Probe one PHT entry: misprediction latency reveals the victim's direction.
static inline int branch_mispredicted(int cond) {
    volatile int sink = 0;
    unsigned long t0 = rdtscp_serialize();
    if (cond)                 // colliding conditional branch: shares a PHT entry with the victim
        sink++;               // taken path — a real conditional branch (a NOP has no prediction state)
    unsigned long t1 = rdtscp_serialize();
    return (t1 - t0) > MISPREDICT_THRESHOLD;   // slow => mispredicted
}
Expected behavior
Target:     directional predictor (PHT of 2-bit counters)
Leak:       taken/not-taken direction of a victim conditional branch
Sharing:    PHT shared across SMT logical cores / contexts
Use cases:  break ASLR-style randomization, recover crypto key bits,
            attack SGX enclave control flow
Signal:     branch-misprediction timing on a colliding attacker branch

Detection

Bir sibling thread üzerindeki anormal branch misprediction oranlarının performance-counter ile izlenmesi; genelde düşük doğruluklu (low-fidelity). Savunmalar önleyici niteliktedir.

Mitigation

Hassas workload'lar için SMT'yi devre dışı bırak; context switch ve enclave girişinde branch predictor'ı flush'la/partition'la; secret'a bağlı kararlar için constant-direction (branchless) kod kullan; oblivious/data-independent algoritmalar tercih et.

References