Spectre PoC - Basado en papel - resultados opuestos

0

Después de una larga discusión con esta pregunta (¡Gracias por la ayuda!)

Espectro de prueba de concepto (PoC) Ejecución especulativa - Comprobación de valor

Llegó con un simple PoC basado en papel Specter.

Parece ser consistente, también se intentó con otro personaje y obtuvo resultados similares.

Ejecución:

user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: E time: 96
trying: X time: 93
trying: W time: 93
trying: F time: 93
trying: O time: 93
trying: J time: 93
trying: C time: 93
trying: K time: 93
trying: Y time: 93
trying: T time: 93
trying: D time: 93
trying: M time: 93
trying: L time: 93
trying: P time: 93
trying: Q time: 93
trying: A time: 93
trying: B time: 93
trying: V time: 93
trying: N time: 93
trying: I time: 93
trying: U time: 93
trying: S time: 93
trying: H time: 93
trying: G time: 93
trying: Z time: 8152
trying: R time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: R time: 96
trying: X time: 92
trying: F time: 93
trying: O time: 93
trying: C time: 93
trying: P time: 93
trying: W time: 93
trying: U time: 93
trying: H time: 93
trying: T time: 93
trying: G time: 93
trying: Z time: 259
trying: K time: 93
trying: V time: 93
trying: J time: 93
trying: D time: 96
trying: M time: 93
trying: Q time: 93
trying: L time: 93
trying: E time: 93
trying: B time: 93
trying: S time: 93
trying: A time: 93
trying: Y time: 93
trying: N time: 93
trying: I time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: S time: 97
trying: W time: 93
trying: C time: 93
trying: V time: 93
trying: K time: 93
trying: P time: 93
trying: T time: 93
trying: Y time: 93
trying: A time: 93
trying: U time: 93
trying: N time: 93
trying: D time: 93
trying: O time: 93
trying: J time: 93
trying: R time: 93
trying: M time: 93
trying: F time: 93
trying: Q time: 93
trying: G time: 93
trying: H time: 93
trying: I time: 93
trying: E time: 93
trying: B time: 93
trying: Z time: 230
trying: L time: 93
trying: X time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: B time: 97
trying: A time: 93
trying: P time: 93
trying: I time: 93
trying: M time: 93
trying: E time: 93
trying: W time: 93
trying: H time: 93
trying: V time: 93
trying: D time: 93
trying: N time: 93
trying: Y time: 93
trying: T time: 93
trying: K time: 93
trying: J time: 93
trying: X time: 93
trying: R time: 93
trying: S time: 93
trying: L time: 93
trying: U time: 93
trying: G time: 93
trying: C time: 93
trying: Z time: 328
trying: O time: 93
trying: Q time: 93
trying: F time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: B time: 97
trying: G time: 93
trying: O time: 93
trying: X time: 93
trying: N time: 93
trying: F time: 93
trying: A time: 93
trying: Q time: 93
trying: Y time: 93
trying: M time: 93
trying: S time: 93
trying: K time: 93
trying: I time: 93
trying: W time: 93
trying: J time: 93
trying: R time: 93
trying: C time: 93
trying: V time: 93
trying: L time: 93
trying: Z time: 272
trying: P time: 93
trying: U time: 93
trying: H time: 92
trying: T time: 93
trying: E time: 93
trying: D time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: R time: 97
trying: A time: 95
trying: M time: 153
trying: F time: 95
trying: H time: 93
trying: L time: 93
trying: D time: 92
trying: G time: 93
trying: K time: 93
trying: U time: 93
trying: S time: 93
trying: W time: 93
trying: O time: 97
trying: Y time: 93
trying: Z time: 289
trying: C time: 93
trying: P time: 93
trying: Q time: 100
trying: B time: 92
trying: J time: 92
trying: I time: 92
trying: V time: 95
trying: E time: 93
trying: X time: 93
trying: T time: 93
trying: N time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: P time: 98
trying: I time: 93
trying: F time: 93
trying: L time: 93
trying: W time: 93
trying: D time: 93
trying: V time: 93
trying: S time: 93
trying: H time: 93
trying: J time: 93
trying: K time: 93
trying: M time: 93
trying: O time: 93
trying: A time: 93
trying: Z time: 363
trying: X time: 93
trying: C time: 93
trying: Y time: 93
trying: E time: 93
trying: Q time: 93
trying: B time: 93
trying: R time: 93
trying: N time: 93
trying: T time: 93
trying: U time: 93
trying: G time: 93

Muestra Spectre PoC

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef _MSC_VER
#include <intrin.h> /* for rdtscp and clflush */
#pragma optimize("gt",on)
#else
#include <x86intrin.h> /* for rdtscp and clflush */
#endif




void main(void)
{
volatile uint8_t array1[26] = { 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90 };

uint8_t array2[256 * 512];

for(int i = 0; i < sizeof(array2); i++)
  array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */


for(int i = 0; i < 256; i++)
  _mm_clflush(&array2[i * 512]); /* intrinsic for clflush instruction */



printf("%c should be cached\n", array1[25]);

int dummy = 0;
for(int i=0; i<26; i++) {
 if (i != 25) {
    array2[array1[i] * 512] = array1[i]; 
 }
}



int t0,time_taken = 0;
int junk = 0;

int mix_i=0;

 int i,j;
    int aux,res;

    char RandomId[26];
    char ListId[26]={65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90};



    srand(time(NULL));

    for(i=0; i<26; i++)
    {
        res = rand() % 26;
        aux = ListId[res];

        if (ListId[res] != -1)
        {
            RandomId[i] = aux;
            ListId[res] = -1;
        }
        else
            i--;
    }



volatile uint8_t * addr;
int y=0;


  for(int i=0; i<26; i++)
  {
    mix_i = RandomId[i];
    addr = &array2[mix_i * 512];
    t0 = __rdtscp(&junk); 
    junk = *addr;
    time_taken = __rdtscp(&junk) - t0;
    if(mix_i>=65 && mix_i<=90)
    printf("trying: %c time: %i\n",mix_i,time_taken);
  }
}

Mi gran pregunta es, sin embargo:

¿Qué tiene de malo? ¿Dónde está mi error?

¿Ya que muestra los tiempos de acceso MAYORES para los valores almacenados en caché (cargados especulativamente)?

Estoy ejecutando el procesador AMD A10-5757M.

    
pregunta android_dev 18.01.2018 - 09:56
fuente

1 respuesta

1

Aquí borras la matriz de la caché -

for(int i = 0; i < 256; i++)
  _mm_clflush(&array2[i * 512]); /* intrinsic for clflush instruction */

Luego lo regresas a la caché

for(int i=0; i<26; i++) {
  if (i != 25) {
    array2[array1[i] * 512] = array1[i]; 
  }
}

Esto sugiere para i == 25 la rama if no se toma (es decir, no se ejecuta de forma especulativa). Todas las demás páginas de la matriz se almacenan en caché, pero la página a la que hace referencia 'Z' no lo está.

Como dije en su pregunta anterior, realmente necesita entender cómo funciona la prueba de concepto que está tratando de replicar antes de llegar a cualquier parte.

En cuanto a por qué no hay una ejecución especulativa, hay varias posibilidades. Por ejemplo, no has intentado entrenar mucho la rama. También es posible que el compilador o el procesador estén optimizando el! = 25 y simplemente reduciendo la declaración "i < 26".

    
respondido por el Hector 18.01.2018 - 10:06
fuente

Lea otras preguntas en las etiquetas