Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kprobes: Prohibit probing on BUG() and WARN() address

Since BUG() and WARN() may use a trap (e.g. UD2 on x86) to
get the address where the BUG() has occurred, kprobes can not
do single-step out-of-line that instruction. So prohibit
probing on such address.

Without this fix, if someone put a kprobe on WARN(), the
kernel will crash with invalid opcode error instead of
outputing warning message, because kernel can not find
correct bug address.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: David S . Miller <davem@davemloft.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Naveen N . Rao <naveen.n.rao@linux.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/156750890133.19112.3393666300746167111.stgit@devnote2
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Masami Hiramatsu and committed by
Ingo Molnar
e336b402 d9f3b450

+7 -1
+5
include/linux/bug.h
··· 47 47 48 48 #else /* !CONFIG_GENERIC_BUG */ 49 49 50 + static inline void *find_bug(unsigned long bugaddr) 51 + { 52 + return NULL; 53 + } 54 + 50 55 static inline enum bug_trap_type report_bug(unsigned long bug_addr, 51 56 struct pt_regs *regs) 52 57 {
+2 -1
kernel/kprobes.c
··· 1514 1514 /* Ensure it is not in reserved area nor out of text */ 1515 1515 if (!kernel_text_address((unsigned long) p->addr) || 1516 1516 within_kprobe_blacklist((unsigned long) p->addr) || 1517 - jump_label_text_reserved(p->addr, p->addr)) { 1517 + jump_label_text_reserved(p->addr, p->addr) || 1518 + find_bug((unsigned long)p->addr)) { 1518 1519 ret = -EINVAL; 1519 1520 goto out; 1520 1521 }