aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Arcangeli <andrea@cpushare.com>2005-03-30 16:31:40 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-30 16:31:40 -0800
commitb053dc29dcde8ec09e85fc71633f5b881d06cc09 (patch)
tree57b5091177b7ac0e90e7db556002986875e9984c
parent192f79194d0aaf354009fe5db4a9f9bf8e885780 (diff)
downloadhistory-b053dc29dcde8ec09e85fc71633f5b881d06cc09.tar.gz
[PATCH] seccomp for ppc64
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 <andrea@cpushare.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/ppc64/Kconfig17
-rw-r--r--arch/ppc64/kernel/ptrace.c3
-rw-r--r--include/asm-i386/seccomp.h16
-rw-r--r--include/asm-ppc64/seccomp.h21
-rw-r--r--include/asm-ppc64/thread_info.h4
-rw-r--r--include/asm-x86_64/seccomp.h24
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/linux/seccomp.h1
-rw-r--r--kernel/seccomp.c32
9 files changed, 93 insertions, 27 deletions
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index eeb9c2ec91182..15c4a1455caee 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -278,6 +278,23 @@ config LPARCFG
Provide system capacity information via human readable
<key word>=<value> 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/<pid>/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 --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index ac89fbdb65b44..354a287c67eb8 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -27,6 +27,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
+#include <linux/seccomp.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -315,6 +316,8 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
+ secure_computing(regs->gpr[0]);
+
if (unlikely(current->audit_context))
audit_syscall_exit(current, regs->result);
diff --git a/include/asm-i386/seccomp.h b/include/asm-i386/seccomp.h
new file mode 100644
index 0000000000000..18da19e89bff2
--- /dev/null
+++ b/include/asm-i386/seccomp.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h>
+
+#ifdef TIF_32BIT
+#error "unexpected TIF_32BIT on i386"
+#endif
+
+#include <linux/unistd.h>
+
+#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 --git a/include/asm-ppc64/seccomp.h b/include/asm-ppc64/seccomp.h
new file mode 100644
index 0000000000000..c130c334bda1c
--- /dev/null
+++ b/include/asm-ppc64/seccomp.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h> /* already defines TIF_32BIT */
+
+#ifndef TIF_32BIT
+#error "unexpected TIF_32BIT on ppc64"
+#endif
+
+#include <linux/unistd.h>
+
+#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 --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index d4b978c26d710..037b5e06083c0 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -101,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
#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<<TIF_SYSCALL_TRACE)
@@ -113,7 +114,8 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED)
diff --git a/include/asm-x86_64/seccomp.h b/include/asm-x86_64/seccomp.h
new file mode 100644
index 0000000000000..553af65a2287a
--- /dev/null
+++ b/include/asm-x86_64/seccomp.h
@@ -0,0 +1,24 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h>
+
+#ifdef TIF_32BIT
+#error "unexpected TIF_32BIT on x86_64"
+#else
+#define TIF_32BIT TIF_IA32
+#endif
+
+#include <linux/unistd.h>
+#include <asm/ia32_unistd.h>
+
+#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 --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index f2a09f442d7dc..a8ea0164f3ab0 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -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 --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ee989b6ee22aa..3a2702bbb1d67 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -8,6 +8,7 @@
#define NR_SECCOMP_MODES 1
#include <linux/thread_info.h>
+#include <asm/seccomp.h>
typedef struct { int mode; } seccomp_t;
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b6c5b35c737c0..c3391b6020e85 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -8,10 +8,6 @@
#include <linux/seccomp.h>
#include <linux/sched.h>
-#include <asm/unistd.h>
-#ifdef TIF_IA32
-#include <asm/ia32_unistd.h>
-#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)