Skip to contentSkip to conversation

seccomp changes for v3.18

GIT PULL Ingo Molnar 1 participant 1 message Oct 13, 2014

Subsystems (6)
Arm (32-bit) x86 MIPS s390 +2 more subsystems
lore
Share & tools
lore
#0 lore raw

Linus,

Please pull the latest x86-seccomp-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-seccomp-for-linus

# HEAD: 1dcf74f6edfc3a9acd84d83d8865dd9e2a3b1d1e x86_64, entry: Use split-phase syscall_trace_enter for 64-bit syscalls

This tree includes x86 seccomp filter speedups and related preparatory work, which touches core seccomp facilities as well.

The main idea is to split seccomp into two phases, to be able to enter a simple fast path for syscalls with ptrace side effects.

There's no substantial user-visible (and ABI) effects expected from this, except a change in how we emit a better audit record for SECCOMP_RET_TRACE events.

out-of-topic modifications in x86-seccomp-for-linus:
------------------------------------------------------

  arch/Kconfig                       # ff27f38e0ef9: seccomp: Document two-phase 
  arch/arm/kernel/ptrace.c           # a4412fc9486e: seccomp,x86,arm,mips,s390: R
  arch/mips/kernel/ptrace.c          # a4412fc9486e: seccomp,x86,arm,mips,s390: R
  arch/s390/kernel/ptrace.c          # a4412fc9486e: seccomp,x86,arm,mips,s390: R
  include/linux/seccomp.h            # d39bd00deabe: seccomp: Allow arch code to 

# 13aa72f0fd0a: seccomp: Refactor the filter # a4412fc9486e: seccomp,x86,arm,mips,s390: R
kernel/seccomp.c # d39bd00deabe: seccomp: Allow arch code to
# 13aa72f0fd0a: seccomp: Refactor the filter # a4412fc9486e: seccomp,x86,arm,mips,s390: R

Thanks,

Ingo

------------------>
Andy Lutomirski (9):
seccomp,x86,arm,mips,s390: Remove nr parameter from secure_computing
seccomp: Refactor the filter callback and the API
seccomp: Allow arch code to provide seccomp_data
seccomp: Document two-phase seccomp and arch-provided seccomp_data x86, x32, audit: Fix x32's AUDIT_ARCH wrt audit
x86, entry: Only call user_exit if TIF_NOHZ
x86: Split syscall_trace_enter into two phases
x86_64, entry: Treat regs->ax the same in fastpath and slowpath syscalls x86_64, entry: Use split-phase syscall_trace_enter for 64-bit syscalls

 arch/Kconfig                   |  11 ++
 arch/arm/kernel/ptrace.c       |   7 +-
 arch/mips/kernel/ptrace.c      |   2 +-
 arch/s390/kernel/ptrace.c      |   2 +-
 arch/x86/include/asm/calling.h |   6 +-
 arch/x86/include/asm/ptrace.h  |   5 +
 arch/x86/kernel/entry_64.S     |  51 ++++-----
 arch/x86/kernel/ptrace.c       | 165 ++++++++++++++++++++++-----
 arch/x86/kernel/vsyscall_64.c  |   2 +-
 include/linux/seccomp.h        |  25 ++--
 kernel/seccomp.c               | 252 ++++++++++++++++++++++++++++-------------
 11 files changed, 371 insertions(+), 157 deletions(-)
arch/Kconfig +11 -0
index 0eae9df35b88..05d7a8a458d5 100644
@@ -323,6 +323,17 @@ config HAVE_ARCH_SECCOMP_FILTER
 	    results in the system call being skipped immediately.
 	  - seccomp syscall wired up
 
+	  For best performance, an arch should use seccomp_phase1 and
+	  seccomp_phase2 directly.  It should call seccomp_phase1 for all
+	  syscalls if TIF_SECCOMP is set, but seccomp_phase1 does not
+	  need to be called from a ptrace-safe context.  It must then
+	  call seccomp_phase2 if seccomp_phase1 returns anything other
+	  than SECCOMP_PHASE1_OK or SECCOMP_PHASE1_SKIP.
+
+	  As an additional optimization, an arch may provide seccomp_data
+	  directly to seccomp_phase1; this avoids multiple calls
+	  to the syscall_xyz helpers for every syscall.
+
 config SECCOMP_FILTER
 	def_bool y
 	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
arch/arm/kernel/ptrace.c +6 -1
index 0c27ed6f3f23..5e772a21ab97 100644
@@ -933,8 +933,13 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
 	current_thread_info()->syscall = scno;
 
 	/* Do the secure computing check first; failures should be fast. */
-	if (secure_computing(scno) == -1)
+#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+	if (secure_computing() == -1)
 		return -1;
+#else
+	/* XXX: remove this once OABI gets fixed */
+	secure_computing_strict(scno);
+#endif
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
arch/mips/kernel/ptrace.c +1 -1
index 645b3c4fcfba..f7aac5b57b4b 100644
@@ -770,7 +770,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
 	long ret = 0;
 	user_exit();
 
-	if (secure_computing(syscall) == -1)
+	if (secure_computing() == -1)
 		return -1;
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
arch/s390/kernel/ptrace.c +1 -1
index 5dc7ad9e2fbf..bebacad48305 100644
@@ -803,7 +803,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 	long ret = 0;
 
 	/* Do the secure computing check first. */
-	if (secure_computing(regs->gprs[2])) {
+	if (secure_computing()) {
 		/* seccomp failures shouldn't expose any additional code. */
 		ret = -1;
 		goto out;
arch/x86/include/asm/calling.h +5 -1
index cb4c73bfeb48..76659b67fd11 100644
@@ -85,7 +85,7 @@ For 32-bit we have the following conventions - kernel is built with
 #define ARGOFFSET	R11
 #define SWFRAME		ORIG_RAX
 
-	.macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1
+	.macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1, rax_enosys=0
 	subq  $9*8+\addskip, %rsp
 	CFI_ADJUST_CFA_OFFSET	9*8+\addskip
 	movq_cfi rdi, 8*8
@@ -96,7 +96,11 @@ For 32-bit we have the following conventions - kernel is built with
 	movq_cfi rcx, 5*8
 	.endif
 
+	.if \rax_enosys
+	movq $-ENOSYS, 4*8(%rsp)
+	.else
 	movq_cfi rax, 4*8
+	.endif
 
 	.if \save_r891011
 	movq_cfi r8,  3*8
arch/x86/include/asm/ptrace.h +5 -0
index 6205f0c434db..86fc2bb82287 100644
@@ -75,6 +75,11 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 			 int error_code, int si_code);
 
+
+extern unsigned long syscall_trace_enter_phase1(struct pt_regs *, u32 arch);
+extern long syscall_trace_enter_phase2(struct pt_regs *, u32 arch,
+				       unsigned long phase1_result);
+
 extern long syscall_trace_enter(struct pt_regs *);
 extern void syscall_trace_leave(struct pt_regs *);
 
arch/x86/kernel/entry_64.S +19 -32

87 lines not on this page · raw message

arch/x86/kernel/ptrace.c +135 -30

199 lines not on this page · raw message

arch/x86/kernel/vsyscall_64.c +1 -1
index e1e1e80fc6a6..957779f4eb40 100644
@@ -216,7 +216,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 	 */
 	regs->orig_ax = syscall_nr;
 	regs->ax = -ENOSYS;
-	tmp = secure_computing(syscall_nr);
+	tmp = secure_computing();
 	if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
 		warn_bad_vsyscall(KERN_DEBUG, regs,
 				  "seccomp tried to change syscall nr or ip");
include/linux/seccomp.h +16 -9
index 5d586a45a319..a19ddacdac30 100644
@@ -27,19 +27,23 @@ struct seccomp {
 	struct seccomp_filter *filter;
 };
 
-extern int __secure_computing(int);
-static inline int secure_computing(int this_syscall)
+#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+extern int __secure_computing(void);
+static inline int secure_computing(void)
 {
 	if (unlikely(test_thread_flag(TIF_SECCOMP)))
-		return  __secure_computing(this_syscall);
+		return  __secure_computing();
 	return 0;
 }
 
-/* A wrapper for architectures supporting only SECCOMP_MODE_STRICT. */
-static inline void secure_computing_strict(int this_syscall)
-{
-	BUG_ON(secure_computing(this_syscall) != 0);
-}
+#define SECCOMP_PHASE1_OK	0
+#define SECCOMP_PHASE1_SKIP	1
+
+extern u32 seccomp_phase1(struct seccomp_data *sd);
+int seccomp_phase2(u32 phase1_result);
+#else
+extern void secure_computing_strict(int this_syscall);
+#endif
 
 extern long prctl_get_seccomp(void);
 extern long prctl_set_seccomp(unsigned long, char __user *);
@@ -56,8 +60,11 @@ static inline int seccomp_mode(struct seccomp *s)
 struct seccomp { };
 struct seccomp_filter { };
 
-static inline int secure_computing(int this_syscall) { return 0; }
+#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+static inline int secure_computing(void) { return 0; }
+#else
 static inline void secure_computing_strict(int this_syscall) { return; }
+#endif
 
 static inline long prctl_get_seccomp(void)
 {
kernel/seccomp.c +171 -81

301 lines not on this page · raw message