seccomp.c 1.7 KB

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