kprobes/x86: Do not jump-optimize kprobes on irq entry code
authorMasami Hiramatsu <mhiramat@kernel.org>
Thu, 3 Aug 2017 02:39:26 +0000 (11:39 +0900)
committerIngo Molnar <mingo@kernel.org>
Thu, 10 Aug 2017 14:28:53 +0000 (16:28 +0200)
Since the kernel segment registers are not prepared at the
entry of irq-entry code, if a kprobe on such code is
jump-optimized, accessing per-CPU variables may cause a
kernel panic.

However, if the kprobe is not optimized, it triggers an int3
exception and sets segment registers correctly.

With this patch we check the probe-address and if it is in the
irq-entry code, it prohibits optimizing such kprobes.

This means we can continue probing such interrupt handlers by kprobes
but it is not optimized anymore.

Reported-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Tested-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: David S . Miller <davem@davemloft.net>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: linux-arch@vger.kernel.org
Cc: linux-cris-kernel@axis.com
Cc: mathieu.desnoyers@efficios.com
Link: http://lkml.kernel.org/r/150172795654.27216.9824039077047777477.stgit@devbox
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/kprobes/opt.c

index 69ea0bc1cfa394c0625f2beb9280db7a273dbafe..4f98aad382378a5987306842ea4fc9cde56972d4 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/insn.h>
 #include <asm/debugreg.h>
 #include <asm/set_memory.h>
+#include <asm/sections.h>
 
 #include "common.h"
 
@@ -251,10 +252,12 @@ static int can_optimize(unsigned long paddr)
 
        /*
         * Do not optimize in the entry code due to the unstable
-        * stack handling.
+        * stack handling and registers setup.
         */
-       if ((paddr >= (unsigned long)__entry_text_start) &&
-           (paddr <  (unsigned long)__entry_text_end))
+       if (((paddr >= (unsigned long)__entry_text_start) &&
+            (paddr <  (unsigned long)__entry_text_end)) ||
+           ((paddr >= (unsigned long)__irqentry_text_start) &&
+            (paddr <  (unsigned long)__irqentry_text_end)))
                return 0;
 
        /* Check there is enough space for a relative jump. */