From: Andrea Arcangeli This patch against 12-rc1 adds seccomp to the ppc64 arch. I tested it successfully with the seccomp_test. I didn't bother to change the syscall exit not to check for TIF_SECCOMP, in theory that bit could be optimized but it's an optimization in the slow path, and current code is a bit simpler. I also verified it still compiles and works fine on x86 and x86-64. Instead of the TIF_32BIT redefine, if you want to change x86-64 to use TIF_32BIT too (instead of TIF_IA32), let me know. Signed-off-by: Andrea Arcangeli Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/Kconfig | 17 +++++++++++++++++ 25-akpm/arch/ppc64/kernel/ptrace.c | 3 +++ 25-akpm/include/asm-i386/seccomp.h | 16 ++++++++++++++++ 25-akpm/include/asm-ppc64/seccomp.h | 21 +++++++++++++++++++++ 25-akpm/include/asm-ppc64/thread_info.h | 4 +++- 25-akpm/include/asm-x86_64/seccomp.h | 24 ++++++++++++++++++++++++ 25-akpm/include/asm-x86_64/unistd.h | 2 +- 25-akpm/include/linux/seccomp.h | 1 + 25-akpm/kernel/seccomp.c | 32 +++++++------------------------- 9 files changed, 93 insertions(+), 27 deletions(-) diff -puN arch/ppc64/Kconfig~seccomp-for-ppc64 arch/ppc64/Kconfig --- 25/arch/ppc64/Kconfig~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/arch/ppc64/Kconfig 2005-03-28 16:14:21.000000000 -0800 @@ -278,6 +278,23 @@ config LPARCFG Provide system capacity information via human readable = pairs through a /proc/ppc64/lparcfg interface. +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + depends on PROC_FS + default y + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via /proc//seccomp, it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + + If unsure, say Y. Only embedded should say N here. + endmenu diff -puN arch/ppc64/kernel/ptrace.c~seccomp-for-ppc64 arch/ppc64/kernel/ptrace.c --- 25/arch/ppc64/kernel/ptrace.c~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/ptrace.c 2005-03-28 16:14:21.000000000 -0800 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -317,6 +318,8 @@ void do_syscall_trace_enter(struct pt_re void do_syscall_trace_leave(struct pt_regs *regs) { + secure_computing(regs->gpr[0]); + if (unlikely(current->audit_context)) audit_syscall_exit(current, (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, diff -puN /dev/null include/asm-i386/seccomp.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/include/asm-i386/seccomp.h 2005-03-28 16:14:21.000000000 -0800 @@ -0,0 +1,16 @@ +#ifndef _ASM_SECCOMP_H + +#include + +#ifdef TIF_32BIT +#error "unexpected TIF_32BIT on i386" +#endif + +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_sigreturn + +#endif /* _ASM_SECCOMP_H */ diff -puN /dev/null include/asm-ppc64/seccomp.h --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/include/asm-ppc64/seccomp.h 2005-03-28 16:14:21.000000000 -0800 @@ -0,0 +1,21 @@ +#ifndef _ASM_SECCOMP_H + +#include /* already defines TIF_32BIT */ + +#ifndef TIF_32BIT +#error "unexpected TIF_32BIT on ppc64" +#endif + +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +#define __NR_seccomp_read_32 __NR_read +#define __NR_seccomp_write_32 __NR_write +#define __NR_seccomp_exit_32 __NR_exit +#define __NR_seccomp_sigreturn_32 __NR_sigreturn + +#endif /* _ASM_SECCOMP_H */ diff -puN include/asm-ppc64/thread_info.h~seccomp-for-ppc64 include/asm-ppc64/thread_info.h --- 25/include/asm-ppc64/thread_info.h~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/include/asm-ppc64/thread_info.h 2005-03-28 16:14:21.000000000 -0800 @@ -101,6 +101,7 @@ static inline struct thread_info *curren #define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ #define TIF_SINGLESTEP 9 /* singlestepping active */ #define TIF_MEMDIE 10 +#define TIF_SECCOMP 11 /* secure computing */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< + +#ifdef TIF_32BIT +#error "unexpected TIF_32BIT on x86_64" +#else +#define TIF_32BIT TIF_IA32 +#endif + +#include +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +#define __NR_seccomp_read_32 __NR_ia32_read +#define __NR_seccomp_write_32 __NR_ia32_write +#define __NR_seccomp_exit_32 __NR_ia32_exit +#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn + +#endif /* _ASM_SECCOMP_H */ diff -puN include/asm-x86_64/unistd.h~seccomp-for-ppc64 include/asm-x86_64/unistd.h --- 25/include/asm-x86_64/unistd.h~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/include/asm-x86_64/unistd.h 2005-03-28 16:14:21.000000000 -0800 @@ -774,7 +774,7 @@ asmlinkage long sys_pipe(int *fildes); asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data); -asmlinkage long sys_iopl(unsigned int level, struct pt_regs regs); +asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs); asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on); struct sigaction; asmlinkage long sys_rt_sigaction(int sig, diff -puN include/linux/seccomp.h~seccomp-for-ppc64 include/linux/seccomp.h --- 25/include/linux/seccomp.h~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/include/linux/seccomp.h 2005-03-28 16:14:21.000000000 -0800 @@ -8,6 +8,7 @@ #define NR_SECCOMP_MODES 1 #include +#include typedef struct { int mode; } seccomp_t; diff -puN kernel/seccomp.c~seccomp-for-ppc64 kernel/seccomp.c --- 25/kernel/seccomp.c~seccomp-for-ppc64 2005-03-28 16:14:21.000000000 -0800 +++ 25-akpm/kernel/seccomp.c 2005-03-28 16:14:21.000000000 -0800 @@ -8,10 +8,6 @@ #include #include -#include -#ifdef TIF_IA32 -#include -#endif /* #define SECCOMP_DEBUG 1 */ @@ -21,27 +17,13 @@ * to limit the stack allocations too. */ static int mode1_syscalls[] = { - __NR_read, __NR_write, __NR_exit, - /* - * Allow either sigreturn or rt_sigreturn, newer archs - * like x86-64 only defines __NR_rt_sigreturn. - */ -#ifdef __NR_sigreturn - __NR_sigreturn, -#else - __NR_rt_sigreturn, -#endif + __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn, 0, /* null terminated */ }; -#ifdef TIF_IA32 -static int mode1_syscalls_32bit[] = { - __NR_ia32_read, __NR_ia32_write, __NR_ia32_exit, - /* - * Allow either sigreturn or rt_sigreturn, newer archs - * like x86-64 only defines __NR_rt_sigreturn. - */ - __NR_ia32_sigreturn, +#ifdef TIF_32BIT +static int mode1_syscalls_32[] = { + __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, 0, /* null terminated */ }; #endif @@ -54,9 +36,9 @@ void __secure_computing(int this_syscall switch (mode) { case 1: syscall = mode1_syscalls; -#ifdef TIF_IA32 - if (test_thread_flag(TIF_IA32)) - syscall = mode1_syscalls_32bit; +#ifdef TIF_32BIT + if (test_thread_flag(TIF_32BIT)) + syscall = mode1_syscalls_32; #endif do { if (*syscall == this_syscall) _