Perché il mio sistema senza patch * appare * per non essere vulnerabile a Spectre?

6

Poiché i corrispondenti documenti di ricerca offrono descrizioni abbastanza esplicite pubblicamente, suppongo che pubblicare il mio codice qui sotto non sia considerato come incoraggiare o sostenere gli exploit. Tuttavia, sono consapevole che alcuni rispondenti potrebbero preferire rimanere un po 'vaghi ...

Mi sono confuso da vari test se i miei sistemi non sono protetti contro le vulnerabilità di Spectre (e Meltdown) dopo l'applicazione delle patch: a volte sembravano in disaccordo o non era chiaro se un ulteriore software necessitasse ancora di un altro patch. Pertanto, intendevo fare i miei test sfruttando effettivamente le vulnerabilità, in contrasto con la maggior parte dei suddetti strumenti di test che leggono piuttosto vari tipi di informazioni su CPU e stato.

Considera il seguente frammento di codice ...

#define CACHELINESIZE   4096
typedef char line[CACHELINESIZE];
line A[512];

char secret = 'H';
char any = 'X';

#define REP     100
char* pcheck[REP];
line* pwrite[REP];
for (int i=0; i<REP; i++) {
  pcheck[i] = &any; 
  pwrite[i] = A; 
}
pcheck[REP-1] = &secret;
pwrite[REP-1] = A+256;
char dummy;
for (int i=0; i<REP; i++) {
  if (i != (REP-1)) {
    dummy = pwrite[i][*pcheck[i]][0];
  }
}

Il if valuta in true 99 volte in una riga (causando un line determinato da other da recuperare nella cache e da leggere da) e poi una volta su false . Quindi presumo che nell'ultima esecuzione, la previsione del ramo sia ingannata nell'esecuzione speculativamente (ma in seguito abbandonando) il compito. In particolare, un line determinato dal contenuto di secret viene recuperato nella cache, anche se il contenuto di secret non è mai "veramente" (cioè, non speculativamente) letto.

Dopodiché, accedo l'accesso alle varie linee e mi aspetto un tempo significativamente più breve per il line determinato dal contenuto di secret (ovvero, la lettura da A[256+'H'] dovrebbe essere più veloce dell'accesso ad altro A[256+c] ).

Tuttavia, misuro costantemente > 1000 cicli per tutti gli accessi di test, mentre mi aspetterei che < 100 cicli per accedere a una linea già memorizzata. (Potrei verificare il tempo più breve cambiando la condizione if e rendendo l'accesso "reale" anziché solo speculativo).

Per me, sembra che la vulnerabilità di Spectre non esista affatto, cioè, il recupero della cache speculativa non si verifica !? Ma l'ho provato in particolare su un sistema che non ha ancora aggiornato kernel / compilatore / BIOS / firmware / microcodice. Almeno questo è ciò che spectre-meltdown-checker.sh sembra per confermare:

Spectre and Meltdown mitigation detection tool v0.29

Checking for vulnerabilities against running kernel Linux 4.4.0-104-generic #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017 x86_64
CPU is Intel(R) Celeron(R) CPU G530 @ 2.40GHz

CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1'
* Checking count of LFENCE opcodes in kernel:  NO 
> STATUS:  VULNERABLE  (only 33 opcodes found, should be >= 70, heuristic to be improved when official patches become available)

CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2'
* Mitigation 1
*   Hardware (CPU microcode) support for mitigation:  NO 
*   Kernel support for IBRS:  NO 
*   IBRS enabled for Kernel space:  NO 
*   IBRS enabled for User space:  NO 
* Mitigation 2
*   Kernel compiled with retpoline option:  NO 
*   Kernel compiled with a retpoline-aware compiler:  NO 
> STATUS:  VULNERABLE  (IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability)

CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3'
* Kernel supports Page Table Isolation (PTI):  NO 
* PTI enabled and active:  NO 
> STATUS:  VULNERABLE  (PTI is needed to mitigate the vulnerability)

A false sense of security is worse than no security at all, see --disclaimer

Quindi - ironia della sorte - quell'ultima riga di questo output sembra essere applicata al mio test interno: non riesce ad esporre la vulnerabilità anche se il sistema è vulnerabile. Q: Ma perché il mio test fallisce in questo modo? Cosa c'è di sbagliato nella mia argomentazione sopra "dimostrare" che dovrebbe esporre la vulnerabilità?

Nota: , naturalmente, ho compilato il mio codice senza ottimizzazione, quindi ti assicuro che l'assemblatore generato corrisponde alla struttura della sorgente (l'ho verificato con objdump ). Inoltre, quanto sopra è solo la versione più basilare del codice che ho provato; per "incoraggiare" la speculazione, ho reso il if dipendente da un calcolo relativamente lungo e il then -body consisteva in una singola istruzione (disassemblata come

   imul   -0x66c(%rbp),%eax
   cmp    %eax,%edx
   je     4006d7 <main+0xf5>
   movzbq (%rdi),%rdi
4006d7: ...
    
posta Hagen von Eitzen 14.01.2018 - 13:39
fonte

1 risposta

1

La ragione per cui il tuo sistema senza patch sembra non essere vulnerabile a Spectre (e Meltdown) è che il tuo processore non è affetto¹ dalla vulnerabilità. Il processore Intel (R) Celeron (R) CPU G530 non è nell'elenco dei prodotti interessati rilasciati da Intel [1]. Il sito Web Spectre / Meltdown [2] afferma solo che "ogni processore Intel che implementa l'esecuzione fuori dall'ordinazione è potenzialmente interessato, che è effettivamente ogni processore dal 1995 (eccetto Intel Itanium e Intel Atom prima del 2013)" [2]. Celeron G530 non implementa l'esecuzione out-of-order o non è interessato dall'exploit o dalla vulnerabilità. Per quanto riguarda il secondo caso, potrebbe essere vulnerabile ma non può essere sfruttato dal tuo exploit o non è vulnerabile nel modo (esatto) in cui il documento lo descrive.

¹ secondo Intel

[1] link
[2] link

    
risposta data 07.02.2018 - 18:22
fonte

Leggi altre domande sui tag