x86/kprobes: Inline kprobe_exceptions_notify() into do_general_protection()
The opaque plumbing of #GP from do_general_protection() through notify_die() into kprobe_exceptions_notify() makes it hard to understand what's going on. Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Jann Horn <jannh@google.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Kees Cook <keescook@chromium.org> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: kernel-hardening@lists.openwall.com Cc: dvyukov@google.com Cc: "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: Alexander Viro <viro@zeniv.linux.org.uk> Cc: linux-fsdevel@vger.kernel.org Cc: Borislav Petkov <bp@alien8.de> Link: https://lkml.kernel.org/r/20180828201421.157735-3-jannh@google.com
This commit is contained in:
parent
a980c0ef9f
commit
76dee4a728
|
@ -1028,42 +1028,13 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
if (fixup_exception(regs, trapnr))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* fixup routine could not handle it,
|
||||
* Let do_page_fault() fix it.
|
||||
*/
|
||||
/* fixup routine could not handle it. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_fault_handler);
|
||||
|
||||
/*
|
||||
* Wrapper routine for handling exceptions.
|
||||
*/
|
||||
int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
struct die_args *args = data;
|
||||
int ret = NOTIFY_DONE;
|
||||
|
||||
if (args->regs && user_mode(args->regs))
|
||||
return ret;
|
||||
|
||||
if (val == DIE_GPF) {
|
||||
/*
|
||||
* To be potentially processing a kprobe fault and to
|
||||
* trust the result from kprobe_running(), we have
|
||||
* be non-preemptible.
|
||||
*/
|
||||
if (!preemptible() && kprobe_running() &&
|
||||
kprobe_fault_handler(args->regs, args->trapnr))
|
||||
ret = NOTIFY_STOP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
NOKPROBE_SYMBOL(kprobe_exceptions_notify);
|
||||
|
||||
bool arch_within_kprobe_blacklist(unsigned long addr)
|
||||
{
|
||||
bool is_in_entry_trampoline_section = false;
|
||||
|
|
|
@ -556,6 +556,16 @@ do_general_protection(struct pt_regs *regs, long error_code)
|
|||
|
||||
tsk->thread.error_code = error_code;
|
||||
tsk->thread.trap_nr = X86_TRAP_GP;
|
||||
|
||||
/*
|
||||
* To be potentially processing a kprobe fault and to
|
||||
* trust the result from kprobe_running(), we have to
|
||||
* be non-preemptible.
|
||||
*/
|
||||
if (!preemptible() && kprobe_running() &&
|
||||
kprobe_fault_handler(regs, X86_TRAP_GP))
|
||||
return;
|
||||
|
||||
if (notify_die(DIE_GPF, "general protection fault", regs, error_code,
|
||||
X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
|
||||
die("general protection fault", regs, error_code);
|
||||
|
|
Loading…
Reference in New Issue