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