linux/kernel/seccomp.c
<<
>>
Prefs
   1/*
   2 * linux/kernel/seccomp.c
   3 *
   4 * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
   5 *
   6 * This defines a simple but solid secure-computing mode.
   7 */
   8
   9#include <linux/seccomp.h>
  10#include <linux/sched.h>
  11#include <linux/compat.h>
  12
  13/* #define SECCOMP_DEBUG 1 */
  14#define NR_SECCOMP_MODES 1
  15
  16/*
  17 * Secure computing mode 1 allows only read/write/exit/sigreturn.
  18 * To be fully secure this must be combined with rlimit
  19 * to limit the stack allocations too.
  20 */
  21static int mode1_syscalls[] = {
  22        __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
  23        0, /* null terminated */
  24};
  25
  26#ifdef CONFIG_COMPAT
  27static int mode1_syscalls_32[] = {
  28        __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
  29        0, /* null terminated */
  30};
  31#endif
  32
  33void __secure_computing(int this_syscall)
  34{
  35        int mode = current->seccomp.mode;
  36        int * syscall;
  37
  38        switch (mode) {
  39        case 1:
  40                syscall = mode1_syscalls;
  41#ifdef CONFIG_COMPAT
  42                if (is_compat_task())
  43                        syscall = mode1_syscalls_32;
  44#endif
  45                do {
  46                        if (*syscall == this_syscall)
  47                                return;
  48                } while (*++syscall);
  49                break;
  50        default:
  51                BUG();
  52        }
  53
  54#ifdef SECCOMP_DEBUG
  55        dump_stack();
  56#endif
  57        do_exit(SIGKILL);
  58}
  59
  60long prctl_get_seccomp(void)
  61{
  62        return current->seccomp.mode;
  63}
  64
  65long prctl_set_seccomp(unsigned long seccomp_mode)
  66{
  67        long ret;
  68
  69        /* can set it only once to be even more secure */
  70        ret = -EPERM;
  71        if (unlikely(current->seccomp.mode))
  72                goto out;
  73
  74        ret = -EINVAL;
  75        if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) {
  76                current->seccomp.mode = seccomp_mode;
  77                set_thread_flag(TIF_SECCOMP);
  78#ifdef TIF_NOTSC
  79                disable_TSC();
  80#endif
  81                ret = 0;
  82        }
  83
  84 out:
  85        return ret;
  86}
  87