Commit 76dee4a7 authored by Jann Horn's avatar Jann Horn Committed by Thomas Gleixner
Browse files

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: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarJann Horn <jannh@google.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarMasami 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
parent a980c0ef
Loading
Loading
Loading
Loading
+1 −30
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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);