kcov: make kcov work properly with KASLR enabled
authorAlexander Popov <[email protected]>
Tue, 20 Dec 2016 00:23:09 +0000 (16:23 -0800)
committerLinus Torvalds <[email protected]>
Tue, 20 Dec 2016 17:48:47 +0000 (09:48 -0800)
Subtract KASLR offset from the kernel addresses reported by kcov.
Tested on x86_64 and AArch64 (Hikey LeMaker).

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Alexander Popov <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Kefeng Wang <[email protected]>
Cc: AKASHI Takahiro <[email protected]>
Cc: Jon Masters <[email protected]>
Cc: David Daney <[email protected]>
Cc: Ganapatrao Kulkarni <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: James Morse <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Alexander Popov <[email protected]>
Cc: syzkaller <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
kernel/kcov.c

index cc2fa35ca480367fe96430ef23ec7b869974c0e7..85e5546cd791cc31261cd6deb8aea933bb41c008 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/kcov.h>
+#include <asm/setup.h>
 
 /*
  * kcov descriptor (one per opened debugfs file).
@@ -73,6 +74,11 @@ void notrace __sanitizer_cov_trace_pc(void)
        if (mode == KCOV_MODE_TRACE) {
                unsigned long *area;
                unsigned long pos;
+               unsigned long ip = _RET_IP_;
+
+#ifdef CONFIG_RANDOMIZE_BASE
+               ip -= kaslr_offset();
+#endif
 
                /*
                 * There is some code that runs in interrupts but for which
@@ -86,7 +92,7 @@ void notrace __sanitizer_cov_trace_pc(void)
                /* The first word is number of subsequent PCs. */
                pos = READ_ONCE(area[0]) + 1;
                if (likely(pos < t->kcov_size)) {
-                       area[pos] = _RET_IP_;
+                       area[pos] = ip;
                        WRITE_ONCE(area[0], pos);
                }
        }