ZombieLoad v2¶
Zaten hardware MDS mitigation'ı taşıyan Intel CPU'larda (Cascade Lake dahil) stale in-flight buffer verisini sample eden, ZombieLoad'un bir TSX Asynchronous Abort (TAA) varyantı (CVE-2019-11135).
Mechanism¶
Note
ZombieLoad v2, MDS'in TSX Asynchronous Abort (TAA) varyantıdır. Intel TSX,
bir thread'in bir hardware transaction (xbegin … xend) çalıştırmasına izin
verir; transaction başka bir ajanla çakışırsa — bir cache-line eviction'ı,
sibling thread'den bir snoop ya da dahili bir buffer koşulu — asenkron olarak
abort edilir. Abort koşulunun ortaya çıkması ile architectural rollback
arasındaki window sırasında, transaction içindeki load'lar, tıpkı orijinal
ZombieLoad fill-buffer leak'indeki gibi, dahili buffer'lardan
(line fill buffer, load port'lar, store buffer) stale data'yı hâlâ
transient olarak forward edebilir.
Kritik fark trigger'dır. İlk MDS dalgası faulting/assisting bir load'a dayanıyordu. Daha yeni parçalar (örn. Cascade Lake) silikon MDS fix'iyle geldi ve MDS-bağışık olarak pazarlandı — ama o fix TSX abort path'ini kapsamadı. TAA, aynı buffer-sampling primitive'ini bir page fault yerine bir TSX transaction üzerinden yeniden kullanır, dolayısıyla "MDS-mitigated" bir CPU hâlâ leak edebilir. Bu yüzden ZombieLoad v2, orijinal MFBDS [CVE-2018-12130]'dan ayrı kendi identifier'ını, CVE-2019-11135'i aldı.
Tüm MDS'lerde olduğu gibi, attacker seçilmiş bir adres yerine in flight olan ne varsa onu sample eder, sonra transient byte'ı cache state'e encode eder ve onu Flush+Reload ile recover eder.
Walkthrough¶
Warning
Yalnızca yetkili araştırma için. Bu, defensive anlayış için kamuya açık, patch'lenmiş TAA primitive'ini belgeler — gösterim amaçlı, tam silahlandırılmış bir exploit değil.
TSX transaction'ı hem speculation window'unu oluşturur hem de abort'u sessizce yutar, bir fault handler ihtiyacını ortadan kaldırır. 256 line'lık bir Flush+Reload oracle'ı alıcıdır:
uint8_t oracle[256 * 4096];
void leak_taa(void *ptr) {
if (_xbegin() == _XBEGIN_STARTED) { // start TSX transaction
uint8_t v = *(volatile uint8_t *)ptr; // transiently forwards STALE buffer byte
// encode into the cache before the transaction aborts/commits
(void)oracle[v * 4096];
_xend();
}
// an async abort here rolls back architecturally, but the cache
// footprint of oracle[v*4096] survives.
}
Alıcı ardından sızmış byte'ı recover etmek için oracle'ı timing'ler:
for (int v = 0; v < 256; v++) {
unsigned t = time_load(&oracle[v * 4096]); // rdtscp around the access
if (t < CACHE_HIT_THRESHOLD) recovered = v;
_mm_clflush(&oracle[v * 4096]); // reset for next round
}
Beklenen davranış
TAA microcode/OS fix'i olmayan, TSX-yetenekli, MDS-hardening yapılmış bir Intel
core'da (örn. Cascade Lake), loop attacker'ın asla yazmadığı bir byte stream'i
verir — core'da ya da onun SMT sibling'inde in flight olan veri. Disclosure,
TAA'nın /etc/shadow'dan root password hash'ini kabaca dört saniyede recover
ettiğini gösterdi; orijinal RIDL timing'inden çok daha hızlı. TSX disable
edildiğinde ya da TAA microcode'u artı transition'larda VERW/MD_CLEAR
buffer clearing ile, oracle yalnızca noise döndürür.
Detection¶
Tüm MDS'ler gibi, abort path architectural bir fault ya da log girdisi bırakmaz.
Kullanışlı sinyaller çevreseldir: yüksek hızda abort eden sık xbegin/xend
transaction'ları gönderen, Flush+Reload timing loop'larıyla birleşmiş process'ler
ve TSX'in disable olup olmadığının ya da TAA mitigation'ının aktif olup olmadığının
platform attestation'ı (Linux durumu
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort üzerinden gösterir).
Mitigation¶
- TSX'i disable et (
tsx=offya daRTM/HLE'yi clear etmeye izin veren microcode): transactional memory'yi kaldırmak, TAA'nın dayandığı abort path'ini ortadan kaldırır. Bu, birincil, en eksiksiz fix'tir. Bkz. TSX Asynchronous Abort mitigation. - MDS'in geri kalanında olduğu gibi, context switch ve VM entry'de
VERW/MD_CLEARbuffer overwrite — bkz. MDS buffer clear (VERW). - Eşzamanlı cross-sibling sampling'i kapatmak için SMT/hyperthreading'i disable et.