seccomp changes for v3.18
Subsystems (6)
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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