seccomp,x86,arm,mips,s390: Remove nr parameter from secure_computing
[firefly-linux-kernel-4.4.55.git] / kernel / seccomp.c
index 25b0043f47551319b6b7afdd9439b79c74a53e0a..5e738e0dd2e9e55bc5017273c8e52bba94df2db4 100644 (file)
 
 /* #define SECCOMP_DEBUG 1 */
 
-#ifdef CONFIG_SECCOMP_FILTER
+#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
 #include <asm/syscall.h>
+#endif
+
+#ifdef CONFIG_SECCOMP_FILTER
 #include <linux/filter.h>
 #include <linux/pid.h>
 #include <linux/ptrace.h>
@@ -172,7 +175,7 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
  *
  * Returns valid seccomp BPF response codes.
  */
-static u32 seccomp_run_filters(int syscall)
+static u32 seccomp_run_filters(void)
 {
        struct seccomp_filter *f = ACCESS_ONCE(current->seccomp.filter);
        struct seccomp_data sd;
@@ -203,7 +206,7 @@ static u32 seccomp_run_filters(int syscall)
 
 static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
 {
-       BUG_ON(!spin_is_locked(&current->sighand->siglock));
+       assert_spin_locked(&current->sighand->siglock);
 
        if (current->seccomp.mode && current->seccomp.mode != seccomp_mode)
                return false;
@@ -214,7 +217,7 @@ static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode)
 static inline void seccomp_assign_mode(struct task_struct *task,
                                       unsigned long seccomp_mode)
 {
-       BUG_ON(!spin_is_locked(&task->sighand->siglock));
+       assert_spin_locked(&task->sighand->siglock);
 
        task->seccomp.mode = seccomp_mode;
        /*
@@ -253,7 +256,7 @@ static inline pid_t seccomp_can_sync_threads(void)
        struct task_struct *thread, *caller;
 
        BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
-       BUG_ON(!spin_is_locked(&current->sighand->siglock));
+       assert_spin_locked(&current->sighand->siglock);
 
        /* Validate all threads being eligible for synchronization. */
        caller = current;
@@ -294,7 +297,7 @@ static inline void seccomp_sync_threads(void)
        struct task_struct *thread, *caller;
 
        BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
-       BUG_ON(!spin_is_locked(&current->sighand->siglock));
+       assert_spin_locked(&current->sighand->siglock);
 
        /* Synchronize all threads. */
        caller = current;
@@ -464,7 +467,7 @@ static long seccomp_attach_filter(unsigned int flags,
        unsigned long total_insns;
        struct seccomp_filter *walker;
 
-       BUG_ON(!spin_is_locked(&current->sighand->siglock));
+       assert_spin_locked(&current->sighand->siglock);
 
        /* Validate resulting filter length. */
        total_insns = filter->prog->len;
@@ -564,10 +567,43 @@ static int mode1_syscalls_32[] = {
 };
 #endif
 
-int __secure_computing(int this_syscall)
+static void __secure_computing_strict(int this_syscall)
+{
+       int *syscall_whitelist = mode1_syscalls;
+#ifdef CONFIG_COMPAT
+       if (is_compat_task())
+               syscall_whitelist = mode1_syscalls_32;
+#endif
+       do {
+               if (*syscall_whitelist == this_syscall)
+                       return;
+       } while (*++syscall_whitelist);
+
+#ifdef SECCOMP_DEBUG
+       dump_stack();
+#endif
+       audit_seccomp(this_syscall, SIGKILL, SECCOMP_RET_KILL);
+       do_exit(SIGKILL);
+}
+
+#ifndef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+void secure_computing_strict(int this_syscall)
+{
+       int mode = current->seccomp.mode;
+
+       if (mode == 0)
+               return;
+       else if (mode == SECCOMP_MODE_STRICT)
+               __secure_computing_strict(this_syscall);
+       else
+               BUG();
+}
+#else
+int __secure_computing(void)
 {
+       struct pt_regs *regs = task_pt_regs(current);
+       int this_syscall = syscall_get_nr(current, regs);
        int exit_sig = 0;
-       int *syscall;
        u32 ret;
 
        /*
@@ -578,23 +614,12 @@ int __secure_computing(int this_syscall)
 
        switch (current->seccomp.mode) {
        case SECCOMP_MODE_STRICT:
-               syscall = mode1_syscalls;
-#ifdef CONFIG_COMPAT
-               if (is_compat_task())
-                       syscall = mode1_syscalls_32;
-#endif
-               do {
-                       if (*syscall == this_syscall)
-                               return 0;
-               } while (*++syscall);
-               exit_sig = SIGKILL;
-               ret = SECCOMP_RET_KILL;
-               break;
+               __secure_computing_strict(this_syscall);
+               return 0;
 #ifdef CONFIG_SECCOMP_FILTER
        case SECCOMP_MODE_FILTER: {
                int data;
-               struct pt_regs *regs = task_pt_regs(current);
-               ret = seccomp_run_filters(this_syscall);
+               ret = seccomp_run_filters();
                data = ret & SECCOMP_RET_DATA;
                ret &= SECCOMP_RET_ACTION;
                switch (ret) {
@@ -652,9 +677,10 @@ int __secure_computing(int this_syscall)
 #ifdef CONFIG_SECCOMP_FILTER
 skip:
        audit_seccomp(this_syscall, exit_sig, ret);
-#endif
        return -1;
+#endif
 }
+#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */
 
 long prctl_get_seccomp(void)
 {