x86/fault: Dump user opcode bytes on fatal faults
authorBorislav Petkov <bp@suse.de>
Tue, 17 Apr 2018 16:11:21 +0000 (18:11 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 26 Apr 2018 14:15:27 +0000 (16:15 +0200)
Sometimes it is useful to see which user opcode bytes RIP points to
when a fault happens: be it to rule out RIP corruption, to dump info
early during boot, when doing core dumps is impossible due to not having
a writable filesystem yet.

Sometimes it is useful if debugging an issue and one doesn't have access
to the executable which caused the fault in order to disassemble it.

That last aspect might have some security implications so
show_unhandled_signals could be revisited for that or a new config option
added.

Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Link: https://lkml.kernel.org/r/20180417161124.5294-7-bp@alien8.de
arch/x86/mm/fault.c

index 73bd8c95ac711d69e551094f15b4534208ea3705..a3fd94eff04d68eaf1a5aa525c515588b2f2aff7 100644 (file)
@@ -828,6 +828,8 @@ static inline void
 show_signal_msg(struct pt_regs *regs, unsigned long error_code,
                unsigned long address, struct task_struct *tsk)
 {
+       const char *loglvl = task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG;
+
        if (!unhandled_signal(tsk, SIGSEGV))
                return;
 
@@ -835,13 +837,14 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
                return;
 
        printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx",
-               task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-               tsk->comm, task_pid_nr(tsk), address,
+               loglvl, tsk->comm, task_pid_nr(tsk), address,
                (void *)regs->ip, (void *)regs->sp, error_code);
 
        print_vma_addr(KERN_CONT " in ", regs->ip);
 
        printk(KERN_CONT "\n");
+
+       show_opcodes((u8 *)regs->ip, loglvl);
 }
 
 static void