arm64: add seccomp support
authorAKASHI Takahiro <takahiro.akashi@linaro.org>
Thu, 4 Sep 2014 15:01:08 +0000 (16:01 +0100)
committerJP Abgrall <jpa@google.com>
Tue, 7 Oct 2014 22:37:32 +0000 (15:37 -0700)
Note: This patch is from v6 of Takahiro's proposed
"arm64: add seccomp support" patchset (leecam@google.com)

secure_computing() is called first in syscall_trace_enter() so that a system
call will be aborted quickly without doing succeeding syscall tracing,
contrary to other cases, if seccomp rules deny that system call.

On compat task, syscall numbers for system calls allowed in seccomp mode 1
are different from those on normal tasks, and so _NR_seccomp_xxx_32's need
to be redefined.

Signed-off-by: AKASHI Takahiro <takahiro.akashi <at> linaro.org>
Conflicts:
arch/arm64/Kconfig
arch/arm64/kernel/entry.S

Change-Id: I5ec44507d7e536df7ec9d62d30a418c26ef15100

arch/arm64/Kconfig
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/seccomp.h [new file with mode: 0644]
arch/arm64/include/asm/unistd.h
arch/arm64/kernel/entry.S
arch/arm64/kernel/ptrace.c

index 2221396c2a6c097eaf13847337000caf3a6c679e..43f1a2ee307c8b4e480036982bbf969c2719b228 100644 (file)
@@ -20,6 +20,7 @@ config ARM64
        select GENERIC_TIME_VSYSCALL
        select HARDIRQS_SW_RESEND
        select HAVE_ARCH_AUDITSYSCALL
+       select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_DEBUG_KMEMLEAK
@@ -232,6 +233,20 @@ config ARMV7_COMPAT_CPUINFO
 
 source "mm/Kconfig"
 
+config SECCOMP
+       bool "Enable seccomp to safely compute untrusted bytecode"
+       ---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 prctl(PR_SET_SECCOMP), it cannot be disabled
+         and the task is only allowed to execute a few safe syscalls
+         defined by each seccomp mode.
+
+
 endmenu
 
 menu "Boot options"
index c0ebe6fade630ef6f124f9a345600290de473055..58768774c7f4094613831ca03159e82df649cff9 100644 (file)
@@ -66,6 +66,7 @@
  * with ptrace(PTRACE_SET_SYSCALL)
  */
 #define RET_SKIP_SYSCALL       -1
+#define RET_SKIP_SYSCALL_TRACE -2
 #define IS_SKIP_SYSCALL(no)    ((int)(no & 0xffffffff) == -1)
 
 #ifndef __ASSEMBLY__
diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h
new file mode 100644 (file)
index 0000000..bec3a43
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * arch/arm64/include/asm/seccomp.h
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi <at> linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_SECCOMP_H
+#define _ASM_SECCOMP_H
+
+#include <asm/unistd.h>
+
+#ifdef CONFIG_COMPAT
+#define __NR_seccomp_read_32           __NR_compat_read
+#define __NR_seccomp_write_32          __NR_compat_write
+#define __NR_seccomp_exit_32           __NR_compat_exit
+#define __NR_seccomp_sigreturn_32      __NR_compat_rt_sigreturn
+#endif /* CONFIG_COMPAT */
+
+#include <asm-generic/seccomp.h>
+
+#endif /* _ASM_SECCOMP_H */
index 53f67c64a6afb17b21f853a07cb0133e4c9c5c6a..2a3957faa70211fc07a39118f19d289cef90ae1b 100644 (file)
@@ -30,6 +30,9 @@
  * Compat syscall numbers used by the AArch64 kernel.
  */
 #define __NR_compat_restart_syscall    0
+#define __NR_compat_exit               1
+#define __NR_compat_read               3
+#define __NR_compat_write              4
 #define __NR_compat_sigreturn          119
 #define __NR_compat_rt_sigreturn       173
 
index a30fab9ea2a30709f34803918677887514655800..8927e52be32f27fa98e26386bee1a93898e904eb 100644 (file)
@@ -663,6 +663,8 @@ __sys_trace:
        mov     x0, sp
        bl      syscall_trace_enter
        adr     lr, __sys_trace_return          // return address
+       cmp     w0, #RET_SKIP_SYSCALL_TRACE     // skip syscall and tracing?
+       b.eq    ret_to_user
        cmp     w0, #RET_SKIP_SYSCALL           // skip syscall?
        b.eq    __sys_trace_return_skipped
        uxtw    scno, w0                        // syscall number (possibly new)
index 2a6edfb0079b237209803549a89a3d2c4720846d..f47e70fed6af77e714601af2afaf247f84772313 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/seccomp.h>
 #include <linux/security.h>
 #include <linux/init.h>
 #include <linux/signal.h>
@@ -1110,6 +1111,10 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
 {
        unsigned int saved_syscallno = regs->syscallno;
 
+       /* Do the secure computing check first; failures should be fast. */
+       if (secure_computing(regs->syscallno) == -1)
+               return RET_SKIP_SYSCALL_TRACE;
+
        if (test_thread_flag(TIF_SYSCALL_TRACE))
                tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);