Skip to content

Spectre-in-eBPF Speculative Store Bypass (v4)

eBPF verifier'ının Speculative Store Bypass mitigation'ını yen, böylece unprivileged bir BPF programı speculatively stale kernel belleğini okuyup onu bir side channel üzerinden sızdırabilsin (CVE-2021-34556 / CVE-2021-35477).

Mechanism

Note

Spectre v4 / SSB (Speculative Store Bypass, namıdiğer store-to-load / STL), CPU'nun memory-disambiguation predictor'ını istismar eder: bir load, aynı adrese yapılan mantıksal olarak daha erken bir store tamamlanmadan önce speculatively execute olabilir, böylece az önce yazılan değer yerine geçici olarak stale bellek döndürür. eBPF verifier'ı bunu, vulnerable bir load'dan önce sanitize edici bir değerin preempting store'unu ekleyerek mitigate eder, böylece speculation altında bile load yalnızca güvenli veri görür. İki bug bu invariant'ı kırdı. CVE-2021-35477: preempting store "yalnızca BPF stack frame pointer'ına bağlı olduğu için 'hızlı' tamamlandığı yanlışlıkla varsayılır," dolayısıyla bağımlı bir load hâlâ ondan önce speculate edebilir. CVE-2021-34556: verifier, belirli bir uninitialized BPF stack slot'una yapılan "ilk store işlemini korumayı asla denemez" ve "BPF stack'i, önceden var olan bellek içeriğinin herhangi bir sanitation'ı olmadan allocate edildiği" için, o korunmamış store'a bağlı sonraki bir load, attacker'ın staged ettiği stale belleği speculatively okuyabilir. Her iki durumda da, "unprivileged bir BPF programı, bir side-channel üzerinden kernel belleğinden hassas bilgi elde edebilir."

Walkthrough

Mitigation primitive'i, BPF nospec instruction'ıdır (BPF_NOSPEC); sanitize edici store ile korunan load arasında emit edilen bir speculation barrier'ına (x86'da lfence) indirilir, böylece load onun ötesine speculate edemez. İki CVE, o barrier'ın (ya da sanitize edici store'un) nereye yerleştirildiğindeki kusurlardır:

  • CVE-2021-35477 için, BPF frame pointer üzerinden geçen dependency chain, sanitize edici store'un bağımlı load'dan sonra reorder edilmesine izin verdi, böylece barrier onu artık korumadı.
  • CVE-2021-34556 için, taze bir stack slot'una yapılan ilk write hiç sanitize edilmedi, böylece o slot'u okuyan bir load, (uninitialized) BPF stack'inde kalan stale byte'ları speculatively açığa çıkarabildi.

Verifier tarafındaki logic, kernel/bpf/verifier.c içindeki SSB sanitization path'inde yaşar.

Warning

Reporter: Piotr Krysiuk; fix'ler Daniel Borkmann tarafından yazıldı. Etkilenen: 5.13.7'ye kadar Linux kernel'i, mainline'da fix'lendi ve stable'a backport edildi (örn. 5.4 serisi). Tam fix commit hash'leri yaygın olarak alıntılanır ama burada fetch edilmedi, bu yüzden belirli hash'leri unverified say.

Detection

Hiçbir memory corruption olmaz — bu bir transient-execution info leak'idir. Risk sinyali, unpatch'li bir kernel'de (≤ 5.13.7) unprivileged BPF program yüklemelerinin varlığıdır.

Mitigation

  • 5.13.7'den yeni bir kernel'e patch'le, ya da bir distro backport'u uygula.
  • kernel.unprivileged_bpf_disabled = 1, unprivileged-load attack surface'ini kaldırır.

References