Blame view

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