lkdtm: flush icache and report actions
authorKees Cook <keescook@chromium.org>
Sun, 9 Feb 2014 21:48:47 +0000 (13:48 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2014 20:30:20 +0000 (12:30 -0800)
Some CPUs explicitly need to have their icache flushed after making
executable code copies for the memory region execution tests.
Additionally, report the specific address targets being used so that
debugging non-crash failures is easier.

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/lkdtm.c

index e910b3c5331c06a74c3a35bba547597b30ce5543..d6ee1aae3e727a3ca24acb151633df8b93f371b3 100644 (file)
@@ -329,7 +329,12 @@ static void execute_location(void *dst)
 {
        void (*func)(void) = dst;
 
+       pr_info("attempting ok execution at %p\n", do_nothing);
+       do_nothing();
+
        memcpy(dst, do_nothing, EXEC_SIZE);
+       flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
+       pr_info("attempting bad execution at %p\n", func);
        func();
 }
 
@@ -338,8 +343,13 @@ static void execute_user_location(void *dst)
        /* Intentionally crossing kernel/user memory boundary. */
        void (*func)(void) = dst;
 
+       pr_info("attempting ok execution at %p\n", do_nothing);
+       do_nothing();
+
        if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE))
                return;
+       flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
+       pr_info("attempting bad execution at %p\n", func);
        func();
 }
 
@@ -464,8 +474,12 @@ static void lkdtm_do_action(enum ctype which)
                }
 
                ptr = (unsigned long *)user_addr;
+
+               pr_info("attempting bad read at %p\n", ptr);
                tmp = *ptr;
                tmp += 0xc0dec0de;
+
+               pr_info("attempting bad write at %p\n", ptr);
                *ptr = tmp;
 
                vm_munmap(user_addr, PAGE_SIZE);
@@ -476,6 +490,8 @@ static void lkdtm_do_action(enum ctype which)
                unsigned long *ptr;
 
                ptr = (unsigned long *)&rodata;
+
+               pr_info("attempting bad write at %p\n", ptr);
                *ptr ^= 0xabcd1234;
 
                break;