All of lore.kernel.org
 help / color / mirror / Atom feed
From: "tip-bot2 for Thomas Gleixner" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Kees Cook <keescook@chromium.org>, x86 <x86@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: [tip: core/entry] entry: Provide generic syscall entry functionality
Date: Fri, 24 Jul 2020 19:08:56 -0000	[thread overview]
Message-ID: <159561773636.4006.6589915651695074984.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20200722220519.513463269@linutronix.de>

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     142781e108b13b2b0e8f035cfb5bfbbc8f14d887
Gitweb:        https://git.kernel.org/tip/142781e108b13b2b0e8f035cfb5bfbbc8f14d887
Author:        Thomas Gleixner <tglx@linutronix.de>
AuthorDate:    Wed, 22 Jul 2020 23:59:56 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 24 Jul 2020 14:59:03 +02:00

entry: Provide generic syscall entry functionality

On syscall entry certain work needs to be done:

   - Establish state (lockdep, context tracking, tracing)
   - Conditional work (ptrace, seccomp, audit...)

This code is needlessly duplicated and  different in all
architectures.

Provide a generic version based on the x86 implementation which has all the
RCU and instrumentation bits right.

As interrupt/exception entry from user space needs parts of the same
functionality, provide a function for this as well.

syscall_enter_from_user_mode() and irqentry_enter_from_user_mode() must be
called right after the low level ASM entry. The calling code must be
non-instrumentable. After the functions returns state is correct and the
subsequent functions can be instrumented.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Kees Cook <keescook@chromium.org>
Link: https://lkml.kernel.org/r/20200722220519.513463269@linutronix.de

---
 arch/Kconfig                 |   3 +-
 include/linux/entry-common.h | 121 ++++++++++++++++++++++++++++++++++-
 kernel/Makefile              |   1 +-
 kernel/entry/Makefile        |  12 +++-
 kernel/entry/common.c        |  88 +++++++++++++++++++++++++-
 5 files changed, 225 insertions(+)
 create mode 100644 include/linux/entry-common.h
 create mode 100644 kernel/entry/Makefile
 create mode 100644 kernel/entry/common.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 8cc35dc..852a527 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -27,6 +27,9 @@ config HAVE_IMA_KEXEC
 config HOTPLUG_SMT
 	bool
 
+config GENERIC_ENTRY
+       bool
+
 config OPROFILE
 	tristate "OProfile system profiling"
 	depends on PROFILING
diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h
new file mode 100644
index 0000000..42fc8e4
--- /dev/null
+++ b/include/linux/entry-common.h
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_ENTRYCOMMON_H
+#define __LINUX_ENTRYCOMMON_H
+
+#include <linux/tracehook.h>
+#include <linux/syscalls.h>
+#include <linux/seccomp.h>
+#include <linux/sched.h>
+
+#include <asm/entry-common.h>
+
+/*
+ * Define dummy _TIF work flags if not defined by the architecture or for
+ * disabled functionality.
+ */
+#ifndef _TIF_SYSCALL_EMU
+# define _TIF_SYSCALL_EMU		(0)
+#endif
+
+#ifndef _TIF_SYSCALL_TRACEPOINT
+# define _TIF_SYSCALL_TRACEPOINT	(0)
+#endif
+
+#ifndef _TIF_SECCOMP
+# define _TIF_SECCOMP			(0)
+#endif
+
+#ifndef _TIF_SYSCALL_AUDIT
+# define _TIF_SYSCALL_AUDIT		(0)
+#endif
+
+/*
+ * TIF flags handled in syscall_enter_from_usermode()
+ */
+#ifndef ARCH_SYSCALL_ENTER_WORK
+# define ARCH_SYSCALL_ENTER_WORK	(0)
+#endif
+
+#define SYSCALL_ENTER_WORK						\
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP |	\
+	 _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_EMU |			\
+	 ARCH_SYSCALL_ENTER_WORK)
+
+/**
+ * arch_check_user_regs - Architecture specific sanity check for user mode regs
+ * @regs:	Pointer to currents pt_regs
+ *
+ * Defaults to an empty implementation. Can be replaced by architecture
+ * specific code.
+ *
+ * Invoked from syscall_enter_from_user_mode() in the non-instrumentable
+ * section. Use __always_inline so the compiler cannot push it out of line
+ * and make it instrumentable.
+ */
+static __always_inline void arch_check_user_regs(struct pt_regs *regs);
+
+#ifndef arch_check_user_regs
+static __always_inline void arch_check_user_regs(struct pt_regs *regs) {}
+#endif
+
+/**
+ * arch_syscall_enter_tracehook - Wrapper around tracehook_report_syscall_entry()
+ * @regs:	Pointer to currents pt_regs
+ *
+ * Returns: 0 on success or an error code to skip the syscall.
+ *
+ * Defaults to tracehook_report_syscall_entry(). Can be replaced by
+ * architecture specific code.
+ *
+ * Invoked from syscall_enter_from_user_mode()
+ */
+static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs);
+
+#ifndef arch_syscall_enter_tracehook
+static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs)
+{
+	return tracehook_report_syscall_entry(regs);
+}
+#endif
+
+/**
+ * syscall_enter_from_user_mode - Check and handle work before invoking
+ *				 a syscall
+ * @regs:	Pointer to currents pt_regs
+ * @syscall:	The syscall number
+ *
+ * Invoked from architecture specific syscall entry code with interrupts
+ * disabled. The calling code has to be non-instrumentable. When the
+ * function returns all state is correct and the subsequent functions can be
+ * instrumented.
+ *
+ * Returns: The original or a modified syscall number
+ *
+ * If the returned syscall number is -1 then the syscall should be
+ * skipped. In this case the caller may invoke syscall_set_error() or
+ * syscall_set_return_value() first.  If neither of those are called and -1
+ * is returned, then the syscall will fail with ENOSYS.
+ *
+ * The following functionality is handled here:
+ *
+ *  1) Establish state (lockdep, RCU (context tracking), tracing)
+ *  2) TIF flag dependent invocations of arch_syscall_enter_tracehook(),
+ *     __secure_computing(), trace_sys_enter()
+ *  3) Invocation of audit_syscall_entry()
+ */
+long syscall_enter_from_user_mode(struct pt_regs *regs, long syscall);
+
+/**
+ * irqentry_enter_from_user_mode - Establish state before invoking the irq handler
+ * @regs:	Pointer to currents pt_regs
+ *
+ * Invoked from architecture specific entry code with interrupts disabled.
+ * Can only be called when the interrupt entry came from user mode. The
+ * calling code must be non-instrumentable.  When the function returns all
+ * state is correct and the subsequent functions can be instrumented.
+ *
+ * The function establishes state (lockdep, RCU (context tracking), tracing)
+ */
+void irqentry_enter_from_user_mode(struct pt_regs *regs);
+
+#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index f3218bc..fde2000 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -48,6 +48,7 @@ obj-y += irq/
 obj-y += rcu/
 obj-y += livepatch/
 obj-y += dma/
+obj-y += entry/
 
 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
 obj-$(CONFIG_FREEZER) += freezer.o
diff --git a/kernel/entry/Makefile b/kernel/entry/Makefile
new file mode 100644
index 0000000..c207d20
--- /dev/null
+++ b/kernel/entry/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Prevent the noinstr section from being pestered by sanitizer and other goodies
+# as long as these things cannot be disabled per function.
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
+KCOV_INSTRUMENT := n
+
+CFLAGS_REMOVE_common.o	 = -fstack-protector -fstack-protector-strong
+CFLAGS_common.o		+= -fno-stack-protector
+
+obj-$(CONFIG_GENERIC_ENTRY) += common.o
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
new file mode 100644
index 0000000..1d636de
--- /dev/null
+++ b/kernel/entry/common.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/context_tracking.h>
+#include <linux/entry-common.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
+/**
+ * enter_from_user_mode - Establish state when coming from user mode
+ *
+ * Syscall/interrupt entry disables interrupts, but user mode is traced as
+ * interrupts enabled. Also with NO_HZ_FULL RCU might be idle.
+ *
+ * 1) Tell lockdep that interrupts are disabled
+ * 2) Invoke context tracking if enabled to reactivate RCU
+ * 3) Trace interrupts off state
+ */
+static __always_inline void enter_from_user_mode(struct pt_regs *regs)
+{
+	arch_check_user_regs(regs);
+	lockdep_hardirqs_off(CALLER_ADDR0);
+
+	CT_WARN_ON(ct_state() != CONTEXT_USER);
+	user_exit_irqoff();
+
+	instrumentation_begin();
+	trace_hardirqs_off_finish();
+	instrumentation_end();
+}
+
+static inline void syscall_enter_audit(struct pt_regs *regs, long syscall)
+{
+	if (unlikely(audit_context())) {
+		unsigned long args[6];
+
+		syscall_get_arguments(current, regs, args);
+		audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
+	}
+}
+
+static long syscall_trace_enter(struct pt_regs *regs, long syscall,
+				unsigned long ti_work)
+{
+	long ret = 0;
+
+	/* Handle ptrace */
+	if (ti_work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) {
+		ret = arch_syscall_enter_tracehook(regs);
+		if (ret || (ti_work & _TIF_SYSCALL_EMU))
+			return -1L;
+	}
+
+	/* Do seccomp after ptrace, to catch any tracer changes. */
+	if (ti_work & _TIF_SECCOMP) {
+		ret = __secure_computing(NULL);
+		if (ret == -1L)
+			return ret;
+	}
+
+	if (unlikely(ti_work & _TIF_SYSCALL_TRACEPOINT))
+		trace_sys_enter(regs, syscall);
+
+	syscall_enter_audit(regs, syscall);
+
+	return ret ? : syscall;
+}
+
+noinstr long syscall_enter_from_user_mode(struct pt_regs *regs, long syscall)
+{
+	unsigned long ti_work;
+
+	enter_from_user_mode(regs);
+	instrumentation_begin();
+
+	local_irq_enable();
+	ti_work = READ_ONCE(current_thread_info()->flags);
+	if (ti_work & SYSCALL_ENTER_WORK)
+		syscall = syscall_trace_enter(regs, syscall, ti_work);
+	instrumentation_end();
+
+	return syscall;
+}
+
+noinstr void irqentry_enter_from_user_mode(struct pt_regs *regs)
+{
+	enter_from_user_mode(regs);
+}

  reply	other threads:[~2020-07-24 19:09 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-22 21:59 [patch V5 00/15] entry, x86, kvm: Generic entry/exit functionality for host and guest Thomas Gleixner
2020-07-22 21:59 ` [patch V5 01/15] seccomp: Provide stub for __secure_computing() Thomas Gleixner
2020-07-24 19:08   ` [tip: core/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 21:59 ` [patch V5 02/15] entry: Provide generic syscall entry functionality Thomas Gleixner
2020-07-24 19:08   ` tip-bot2 for Thomas Gleixner [this message]
2020-07-22 21:59 ` [patch V5 03/15] entry: Provide generic syscall exit function Thomas Gleixner
2020-07-24 19:08   ` [tip: core/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 21:59 ` [patch V5 04/15] entry: Provide generic interrupt entry/exit code Thomas Gleixner
2020-07-24 19:08   ` [tip: core/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 21:59 ` [patch V5 05/15] entry: Provide infrastructure for work before transitioning to guest mode Thomas Gleixner
2020-07-24 19:08   ` [tip: core/entry] " tip-bot2 for Thomas Gleixner
2020-07-29 16:55   ` [patch V5 05/15] " Qian Cai
2020-07-30  7:19     ` Thomas Gleixner
2020-07-30 10:34       ` [tip: x86/entry] x86/kvm: Use __xfer_to_guest_mode_work_pending() in kvm_run_vcpu() tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 06/15] x86/entry: Consolidate check_user_regs() Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 07/15] x86/entry: Consolidate 32/64 bit syscall entry Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-26 18:33     ` Brian Gerst
2020-07-27 13:38       ` Thomas Gleixner
2020-07-22 22:00 ` [patch V5 08/15] x86/entry: Move user return notifier out of loop Thomas Gleixner
2020-07-23 23:41   ` Sean Christopherson
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 09/15] x86/ptrace: Provide pt_regs helper for entry/exit Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 10/15] x86/entry: Use generic syscall entry function Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 11/15] x86/entry: Use generic syscall exit functionality Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 12/15] x86/entry: Cleanup idtentry_entry/exit_user Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 13/15] x86/entry: Use generic interrupt entry/exit code Thomas Gleixner
2020-07-24 14:28   ` Ingo Molnar
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 14/15] x86/entry: Cleanup idtentry_enter/exit Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-22 22:00 ` [patch V5 15/15] x86/kvm: Use generic xfer to guest work function Thomas Gleixner
2020-07-24  0:17   ` Sean Christopherson
2020-07-24  0:46     ` Thomas Gleixner
2020-07-24  0:55       ` Sean Christopherson
2020-07-24 14:24   ` Ingo Molnar
2020-07-24 19:08     ` Thomas Gleixner
2020-07-24 20:11   ` [tip: x86/entry] " tip-bot2 for Thomas Gleixner
2020-07-24 20:51 ` [patch V5 00/15] entry, x86, kvm: Generic entry/exit functionality for host and guest Thomas Gleixner
2020-07-29 13:39   ` Steven Price

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=159561773636.4006.6589915651695074984.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.