seccompsandbox.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. /*
  2. * Part of Very Secure FTPd
  3. * Licence: GPL v2
  4. * Author: Chris Evans
  5. * seccompsandbox.c
  6. *
  7. * Code to lock down the accessible kernel API in a Linux seccomp filter
  8. * sandbox. Works in Ubuntu 11.10 and newer.
  9. */
  10. #include "seccompsandbox.h"
  11. #if defined(__linux__) && defined(__x86_64__)
  12. #include "session.h"
  13. #include "sysutil.h"
  14. #include "tunables.h"
  15. #include "utility.h"
  16. #include <errno.h>
  17. #include <netinet/in.h>
  18. #include <netinet/tcp.h>
  19. #include <sys/fcntl.h>
  20. #include <sys/mman.h>
  21. #include <sys/prctl.h>
  22. #include <sys/socket.h>
  23. #include <sys/types.h>
  24. #include <linux/filter.h>
  25. #include <asm/unistd.h>
  26. /* #define DEBUG_SIGSYS 1 */
  27. #ifndef PR_SET_SECCOMP
  28. #define PR_SET_SECCOMP 22
  29. #endif
  30. #ifndef PR_SET_NO_NEW_PRIVS
  31. #define PR_SET_NO_NEW_PRIVS 38
  32. #endif
  33. #ifndef __NR_openat
  34. #define __NR_openat 257
  35. #endif
  36. #ifndef O_LARGEFILE
  37. #define O_LARGEFILE 00100000
  38. #endif
  39. #ifndef O_DIRECTORY
  40. #define O_DIRECTORY 00200000
  41. #endif
  42. #ifndef O_CLOEXEC
  43. #define O_CLOEXEC 002000000
  44. #endif
  45. #define kMaxSyscalls 100
  46. #ifdef DEBUG_SIGSYS
  47. #include <signal.h>
  48. #include <string.h>
  49. void
  50. handle_sigsys(int sig)
  51. {
  52. (void) sig;
  53. }
  54. #endif
  55. static const int kOpenFlags =
  56. O_CREAT|O_EXCL|O_APPEND|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_LARGEFILE;
  57. static size_t s_syscall_index;
  58. static size_t s_1_arg_validations;
  59. static size_t s_2_arg_validations;
  60. static size_t s_3_arg_validations;
  61. static int s_syscalls[kMaxSyscalls];
  62. static int s_errnos[kMaxSyscalls];
  63. static int s_args_1[kMaxSyscalls];
  64. static int s_vals_1[kMaxSyscalls];
  65. static int s_args_2[kMaxSyscalls];
  66. static int s_vals_2[kMaxSyscalls];
  67. static int s_args_3[kMaxSyscalls];
  68. static int s_vals_3[kMaxSyscalls];
  69. static void
  70. allow_nr(int nr)
  71. {
  72. if (s_syscall_index >= kMaxSyscalls)
  73. {
  74. bug("out of syscall space");
  75. }
  76. if (nr < 0)
  77. {
  78. bug("negative syscall");
  79. }
  80. s_errnos[s_syscall_index] = 0;
  81. s_syscalls[s_syscall_index++] = nr;
  82. }
  83. static void
  84. reject_nr(int nr, int errcode)
  85. {
  86. if (s_syscall_index >= kMaxSyscalls)
  87. {
  88. bug("out of syscall space");
  89. }
  90. if (nr < 0)
  91. {
  92. bug("negative syscall");
  93. }
  94. if (errcode < 0 || errcode > 255)
  95. {
  96. bug("bad errcode");
  97. }
  98. s_errnos[s_syscall_index] = errcode;
  99. s_syscalls[s_syscall_index++] = nr;
  100. }
  101. static void
  102. allow_nr_1_arg_match(int nr, int arg, int val)
  103. {
  104. if (s_syscall_index >= kMaxSyscalls)
  105. {
  106. bug("out of syscall space");
  107. }
  108. if (nr < 0)
  109. {
  110. bug("negative syscall");
  111. }
  112. if (arg < 1 || arg > 6)
  113. {
  114. bug("arg out of range");
  115. }
  116. s_args_1[s_syscall_index] = arg;
  117. s_vals_1[s_syscall_index] = val;
  118. s_errnos[s_syscall_index] = 0;
  119. s_syscalls[s_syscall_index++] = nr;
  120. s_1_arg_validations++;
  121. }
  122. static void
  123. allow_nr_1_arg_mask(int nr, int arg, int val)
  124. {
  125. if (s_syscall_index >= kMaxSyscalls)
  126. {
  127. bug("out of syscall space");
  128. }
  129. if (nr < 0)
  130. {
  131. bug("negative syscall");
  132. }
  133. if (arg < 1 || arg > 6)
  134. {
  135. bug("arg out of range");
  136. }
  137. s_args_1[s_syscall_index] = 100 + arg;
  138. s_vals_1[s_syscall_index] = val;
  139. s_errnos[s_syscall_index] = 0;
  140. s_syscalls[s_syscall_index++] = nr;
  141. s_1_arg_validations++;
  142. }
  143. static void
  144. allow_nr_2_arg_match(int nr, int arg1, int val1, int arg2, int val2)
  145. {
  146. if (s_syscall_index >= kMaxSyscalls)
  147. {
  148. bug("out of syscall space");
  149. }
  150. if (nr < 0)
  151. {
  152. bug("negative syscall");
  153. }
  154. if (arg1 < 1 || arg1 > 6)
  155. {
  156. bug("arg1 out of range");
  157. }
  158. if (arg2 < 1 || arg2 > 6)
  159. {
  160. bug("arg2 out of range");
  161. }
  162. s_args_1[s_syscall_index] = arg1;
  163. s_vals_1[s_syscall_index] = val1;
  164. s_args_2[s_syscall_index] = arg2;
  165. s_vals_2[s_syscall_index] = val2;
  166. s_errnos[s_syscall_index] = 0;
  167. s_syscalls[s_syscall_index++] = nr;
  168. s_2_arg_validations++;
  169. }
  170. static void
  171. allow_nr_2_arg_mask_match(int nr, int arg1, int val1, int arg2, int val2)
  172. {
  173. if (s_syscall_index >= kMaxSyscalls)
  174. {
  175. bug("out of syscall space");
  176. }
  177. if (nr < 0)
  178. {
  179. bug("negative syscall");
  180. }
  181. if (arg1 < 1 || arg1 > 6)
  182. {
  183. bug("arg1 out of range");
  184. }
  185. if (arg2 < 1 || arg2 > 6)
  186. {
  187. bug("arg2 out of range");
  188. }
  189. s_args_1[s_syscall_index] = 100 + arg1;
  190. s_vals_1[s_syscall_index] = val1;
  191. s_args_2[s_syscall_index] = arg2;
  192. s_vals_2[s_syscall_index] = val2;
  193. s_errnos[s_syscall_index] = 0;
  194. s_syscalls[s_syscall_index++] = nr;
  195. s_2_arg_validations++;
  196. }
  197. static void
  198. allow_nr_3_arg_match(int nr, int arg1, int val1, int arg2, int val2, int arg3,
  199. int val3)
  200. {
  201. if (s_syscall_index >= kMaxSyscalls)
  202. {
  203. bug("out of syscall space");
  204. }
  205. if (nr < 0)
  206. {
  207. bug("negative syscall");
  208. }
  209. if (arg1 < 1 || arg1 > 6)
  210. {
  211. bug("arg1 out of range");
  212. }
  213. if (arg2 < 1 || arg2 > 6)
  214. {
  215. bug("arg2 out of range");
  216. }
  217. if (arg3 < 1 || arg3 > 6)
  218. {
  219. bug("arg3 out of range");
  220. }
  221. s_args_1[s_syscall_index] = arg1;
  222. s_vals_1[s_syscall_index] = val1;
  223. s_args_2[s_syscall_index] = arg2;
  224. s_vals_2[s_syscall_index] = val2;
  225. s_args_3[s_syscall_index] = arg3;
  226. s_vals_3[s_syscall_index] = val3;
  227. s_errnos[s_syscall_index] = 0;
  228. s_syscalls[s_syscall_index++] = nr;
  229. s_3_arg_validations++;
  230. }
  231. static void
  232. seccomp_sandbox_setup_data_connections()
  233. {
  234. allow_nr_3_arg_match(__NR_socket, 1, PF_INET, 2, SOCK_STREAM, 3, IPPROTO_TCP);
  235. allow_nr_3_arg_match(__NR_socket,
  236. 1, PF_INET6,
  237. 2, SOCK_STREAM,
  238. 3, IPPROTO_TCP);
  239. allow_nr(__NR_bind);
  240. allow_nr(__NR_select);
  241. if (tunable_port_enable)
  242. {
  243. allow_nr(__NR_connect);
  244. allow_nr_2_arg_match(__NR_getsockopt, 2, SOL_SOCKET, 3, SO_ERROR);
  245. allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_REUSEADDR);
  246. allow_nr_1_arg_match(__NR_fcntl, 2, F_GETFL);
  247. allow_nr_2_arg_match(__NR_fcntl, 2, F_SETFL, 3, O_RDWR|O_NONBLOCK);
  248. allow_nr_2_arg_match(__NR_fcntl, 2, F_SETFL, 3, O_RDWR);
  249. }
  250. if (tunable_pasv_enable)
  251. {
  252. allow_nr(__NR_listen);
  253. allow_nr(__NR_accept);
  254. }
  255. }
  256. static void
  257. seccomp_sandbox_setup_base()
  258. {
  259. /* Simple reads and writes on existing descriptors. */
  260. allow_nr(__NR_read);
  261. allow_nr(__NR_write);
  262. /* Needed for memory management. */
  263. allow_nr_2_arg_match(__NR_mmap,
  264. 3, PROT_READ|PROT_WRITE,
  265. 4, MAP_PRIVATE|MAP_ANON);
  266. allow_nr_1_arg_mask(__NR_mprotect, 3, PROT_READ);
  267. allow_nr(__NR_munmap);
  268. allow_nr(__NR_brk);
  269. /* glibc falls back gracefully if mremap() fails during realloc(). */
  270. reject_nr(__NR_mremap, ENOSYS);
  271. /* Misc simple low-risk calls. */
  272. allow_nr(__NR_gettimeofday); /* Used by logging. */
  273. allow_nr(__NR_rt_sigreturn); /* Used to handle SIGPIPE. */
  274. allow_nr(__NR_restart_syscall);
  275. allow_nr(__NR_close);
  276. /* Always need to be able to exit ! */
  277. allow_nr(__NR_exit_group);
  278. }
  279. void
  280. seccomp_sandbox_init()
  281. {
  282. if (s_syscall_index != 0)
  283. {
  284. bug("bad state in seccomp_sandbox_init");
  285. }
  286. }
  287. void
  288. seccomp_sandbox_setup_prelogin(const struct vsf_session* p_sess)
  289. {
  290. (void) p_sess;
  291. seccomp_sandbox_setup_base();
  292. /* Peeking FTP commands from the network. */
  293. allow_nr_1_arg_match(__NR_recvfrom, 4, MSG_PEEK);
  294. /* Misc simple low-risk calls */
  295. allow_nr(__NR_nanosleep); /* Used for bandwidth / login throttling. */
  296. allow_nr(__NR_getpid); /* Used by logging. */
  297. allow_nr(__NR_shutdown); /* Used for QUIT or a timeout. */
  298. allow_nr_1_arg_match(__NR_fcntl, 2, F_GETFL);
  299. /* It's safe to allow O_RDWR in fcntl because these flags cannot be changed.
  300. * Also, sockets are O_RDWR.
  301. */
  302. allow_nr_2_arg_mask_match(__NR_fcntl, 3, kOpenFlags|O_ACCMODE, 2, F_SETFL);
  303. /* Config-dependent items follow. */
  304. if (tunable_idle_session_timeout > 0)
  305. {
  306. allow_nr(__NR_rt_sigaction);
  307. allow_nr(__NR_alarm);
  308. }
  309. if (tunable_xferlog_enable || tunable_dual_log_enable)
  310. {
  311. /* For file locking. */
  312. allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLKW);
  313. allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLK);
  314. }
  315. if (tunable_ssl_enable)
  316. {
  317. allow_nr_1_arg_match(__NR_recvmsg, 3, 0);
  318. allow_nr_2_arg_match(__NR_setsockopt, 2, IPPROTO_TCP, 3, TCP_NODELAY);
  319. }
  320. if (tunable_syslog_enable)
  321. {
  322. reject_nr(__NR_socket, EACCES);
  323. }
  324. }
  325. void
  326. seccomp_sandbox_setup_postlogin(const struct vsf_session* p_sess)
  327. {
  328. int is_anon = p_sess->is_anonymous;
  329. int open_flag = kOpenFlags;
  330. if (tunable_write_enable)
  331. {
  332. open_flag |= O_ACCMODE;
  333. }
  334. /* Put lstat() first because it is a very hot syscall for large directory
  335. * listings. And the current BPF only allows a linear scan of allowed
  336. * syscalls.
  337. */
  338. allow_nr(__NR_lstat);
  339. /* Allow all the simple pre-login things and then expand upon them. */
  340. seccomp_sandbox_setup_prelogin(p_sess);
  341. /* Simple file descriptor-based operations. */
  342. if (tunable_xferlog_enable || tunable_dual_log_enable ||
  343. tunable_lock_upload_files)
  344. {
  345. allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLKW);
  346. allow_nr_1_arg_match(__NR_fcntl, 2, F_SETLK);
  347. }
  348. if (tunable_async_abor_enable)
  349. {
  350. allow_nr_2_arg_match(__NR_fcntl, 2, F_SETOWN, 3, vsf_sysutil_getpid());
  351. }
  352. allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_KEEPALIVE);
  353. allow_nr_2_arg_match(__NR_setsockopt, 2, SOL_SOCKET, 3, SO_LINGER);
  354. allow_nr_2_arg_match(__NR_setsockopt, 2, IPPROTO_IP, 3, IP_TOS);
  355. allow_nr(__NR_fstat);
  356. allow_nr(__NR_lseek);
  357. /* Since we use chroot() to restrict filesystem access, we can just blanket
  358. * allow open().
  359. */
  360. allow_nr_1_arg_mask(__NR_open, 2, open_flag);
  361. allow_nr_1_arg_mask(__NR_openat, 3, open_flag);
  362. /* Other pathname-based metadata queries. */
  363. allow_nr(__NR_stat);
  364. allow_nr(__NR_readlink);
  365. /* Directory handling: query, change, read. */
  366. allow_nr(__NR_getcwd);
  367. allow_nr(__NR_chdir);
  368. allow_nr(__NR_getdents);
  369. /* Misc */
  370. allow_nr(__NR_umask);
  371. /* Config-dependent items follow. */
  372. if (tunable_use_sendfile)
  373. {
  374. allow_nr(__NR_sendfile);
  375. }
  376. if (tunable_idle_session_timeout > 0 ||
  377. tunable_data_connection_timeout > 0 ||
  378. tunable_async_abor_enable)
  379. {
  380. allow_nr(__NR_rt_sigaction);
  381. }
  382. if (tunable_idle_session_timeout > 0 || tunable_data_connection_timeout > 0)
  383. {
  384. allow_nr(__NR_alarm);
  385. }
  386. if (tunable_one_process_model)
  387. {
  388. seccomp_sandbox_setup_data_connections();
  389. if (is_anon && tunable_chown_uploads)
  390. {
  391. allow_nr(__NR_fchmod);
  392. allow_nr(__NR_fchown);
  393. }
  394. }
  395. else
  396. {
  397. /* Need to receieve file descriptors from privileged broker. */
  398. allow_nr_1_arg_match(__NR_recvmsg, 3, 0);
  399. if ((is_anon && tunable_chown_uploads) || tunable_ssl_enable)
  400. {
  401. /* Need to send file descriptors to privileged broker. */
  402. allow_nr_1_arg_match(__NR_sendmsg, 3, 0);
  403. }
  404. }
  405. if (tunable_syslog_enable)
  406. {
  407. /* The ability to pass an address spec isn't needed so disable it. We ensure
  408. * the 6th arg (socklen) is 0. We could have checked the 5th arg (sockptr)
  409. * but I don't know if 64-bit compares work in the kernel filter, so we're
  410. * happy to check the socklen arg, which is 32 bits.
  411. */
  412. allow_nr_1_arg_match(__NR_sendto, 6, 0);
  413. }
  414. if (tunable_text_userdb_names)
  415. {
  416. reject_nr(__NR_socket, EACCES);
  417. allow_nr_2_arg_match(__NR_mmap, 3, PROT_READ, 4, MAP_SHARED);
  418. }
  419. if (tunable_write_enable)
  420. {
  421. if (!is_anon || tunable_anon_mkdir_write_enable)
  422. {
  423. allow_nr(__NR_mkdir);
  424. }
  425. if (!is_anon ||
  426. tunable_anon_other_write_enable ||
  427. tunable_delete_failed_uploads)
  428. {
  429. allow_nr(__NR_unlink);
  430. }
  431. if (!is_anon || tunable_anon_other_write_enable)
  432. {
  433. allow_nr(__NR_rmdir);
  434. allow_nr(__NR_rename);
  435. allow_nr(__NR_ftruncate);
  436. if (tunable_mdtm_write)
  437. {
  438. allow_nr(__NR_utime);
  439. allow_nr(__NR_utimes);
  440. }
  441. }
  442. if (!is_anon && tunable_chmod_enable)
  443. {
  444. allow_nr(__NR_chmod);
  445. }
  446. }
  447. }
  448. void
  449. seccomp_sandbox_setup_postlogin_broker()
  450. {
  451. seccomp_sandbox_setup_base();
  452. seccomp_sandbox_setup_data_connections();
  453. allow_nr_1_arg_match(__NR_sendmsg, 3, 0);
  454. }
  455. void
  456. seccomp_sandbox_lockdown()
  457. {
  458. size_t len = (s_syscall_index * 2) +
  459. (s_1_arg_validations * 3) +
  460. (s_2_arg_validations * 5) +
  461. (s_3_arg_validations * 7) +
  462. 5;
  463. struct sock_filter filters[len];
  464. struct sock_filter* p_filter = filters;
  465. struct sock_fprog prog;
  466. size_t i;
  467. int ret;
  468. prog.len = len;
  469. prog.filter = filters;
  470. /* Validate the syscall architecture. */
  471. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  472. p_filter->jt = 0;
  473. p_filter->jf = 0;
  474. /* Offset 4 for syscall architecture. */
  475. p_filter->k = 4;
  476. p_filter++;
  477. p_filter->code = BPF_JMP+BPF_JEQ+BPF_K;
  478. p_filter->jt = 1;
  479. p_filter->jf = 0;
  480. /* AUDIT_ARCH_X86_64 */
  481. p_filter->k = 0xc000003e;
  482. p_filter++;
  483. p_filter->code = BPF_RET+BPF_K;
  484. p_filter->jt = 0;
  485. p_filter->jf = 0;
  486. /* SECCOMP_RET_KILL */
  487. p_filter->k = 0;
  488. p_filter++;
  489. /* Load the syscall number. */
  490. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  491. p_filter->jt = 0;
  492. p_filter->jf = 0;
  493. /* Offset 0 for syscall number. */
  494. p_filter->k = 0;
  495. p_filter++;
  496. for (i = 0; i < s_syscall_index; ++i)
  497. {
  498. int block_size = 1;
  499. if (s_args_3[i])
  500. {
  501. block_size = 8;
  502. }
  503. else if (s_args_2[i])
  504. {
  505. block_size = 6;
  506. }
  507. else if (s_args_1[i])
  508. {
  509. block_size = 4;
  510. }
  511. /* Check for syscall number match. */
  512. p_filter->code = BPF_JMP+BPF_JEQ+BPF_K;
  513. p_filter->jt = 0;
  514. p_filter->jf = block_size;
  515. p_filter->k = s_syscalls[i];
  516. p_filter++;
  517. /* Check argument matches if necessary. */
  518. if (s_args_3[i])
  519. {
  520. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  521. p_filter->jt = 0;
  522. p_filter->jf = 0;
  523. p_filter->k = 16 + ((s_args_3[i] - 1) * 8);
  524. p_filter++;
  525. p_filter->code = BPF_JMP+BPF_JEQ+BPF_K;
  526. p_filter->jt = 0;
  527. p_filter->jf = 5;
  528. p_filter->k = s_vals_3[i];
  529. p_filter++;
  530. }
  531. if (s_args_2[i])
  532. {
  533. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  534. p_filter->jt = 0;
  535. p_filter->jf = 0;
  536. p_filter->k = 16 + ((s_args_2[i] - 1) * 8);
  537. p_filter++;
  538. p_filter->code = BPF_JMP+BPF_JEQ+BPF_K;
  539. p_filter->jt = 0;
  540. p_filter->jf = 3;
  541. p_filter->k = s_vals_2[i];
  542. p_filter++;
  543. }
  544. if (s_args_1[i])
  545. {
  546. int arg = s_args_1[i];
  547. int code = BPF_JMP+BPF_JEQ+BPF_K;
  548. int val = s_vals_1[i];
  549. int jt = 0;
  550. int jf = 1;
  551. if (arg > 100)
  552. {
  553. arg -= 100;
  554. code = BPF_JMP+BPF_JSET+BPF_K;
  555. val = ~val;
  556. jt = 1;
  557. jf = 0;
  558. }
  559. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  560. p_filter->jt = 0;
  561. p_filter->jf = 0;
  562. p_filter->k = 16 + ((arg - 1) * 8);
  563. p_filter++;
  564. p_filter->code = code;
  565. p_filter->jt = jt;
  566. p_filter->jf = jf;
  567. p_filter->k = val;
  568. p_filter++;
  569. }
  570. p_filter->code = BPF_RET+BPF_K;
  571. p_filter->jt = 0;
  572. p_filter->jf = 0;
  573. if (!s_errnos[i])
  574. {
  575. /* SECCOMP_RET_ALLOW */
  576. p_filter->k = 0x7fff0000;
  577. }
  578. else
  579. {
  580. /* SECCOMP_RET_ERRNO */
  581. p_filter->k = 0x00050000 + s_errnos[i];
  582. }
  583. p_filter++;
  584. if (s_args_1[i])
  585. {
  586. /* We trashed the accumulator so put it back. */
  587. p_filter->code = BPF_LD+BPF_W+BPF_ABS;
  588. p_filter->jt = 0;
  589. p_filter->jf = 0;
  590. p_filter->k = 0;
  591. p_filter++;
  592. }
  593. }
  594. /* No "allow" matches so kill. */
  595. p_filter->code = BPF_RET+BPF_K;
  596. p_filter->jt = 0;
  597. p_filter->jf = 0;
  598. #ifdef DEBUG_SIGSYS
  599. /* SECCOMP_RET_TRAP */
  600. p_filter->k = 0x00030000;
  601. #else
  602. /* SECCOMP_RET_KILL */
  603. p_filter->k = 0;
  604. #endif
  605. ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
  606. if (ret != 0)
  607. {
  608. if (errno == EINVAL)
  609. {
  610. /* Kernel isn't good enough. */
  611. return;
  612. }
  613. die("prctl PR_SET_NO_NEW_PRIVS");
  614. }
  615. if (!tunable_seccomp_sandbox)
  616. {
  617. return;
  618. }
  619. #ifdef DEBUG_SIGSYS
  620. {
  621. struct sigaction sa;
  622. memset(&sa, '\0', sizeof(sa));
  623. sa.sa_handler = handle_sigsys;
  624. sigaction(SIGSYS, &sa, NULL);
  625. }
  626. #endif
  627. ret = prctl(PR_SET_SECCOMP, 2, &prog, 0, 0);
  628. if (ret != 0)
  629. {
  630. if (errno == EINVAL)
  631. {
  632. /* Kernel isn't good enough. */
  633. return;
  634. }
  635. die("prctl PR_SET_SECCOMP failed");
  636. }
  637. }
  638. #else /* __linux__ && __x86_64__ */
  639. void
  640. seccomp_sandbox_init()
  641. {
  642. }
  643. void
  644. seccomp_sandbox_setup_prelogin(const struct vsf_session* p_sess)
  645. {
  646. (void) p_sess;
  647. }
  648. void
  649. seccomp_sandbox_setup_postlogin(const struct vsf_session* p_sess)
  650. {
  651. (void) p_sess;
  652. }
  653. void
  654. seccomp_sandbox_setup_postlogin_broker()
  655. {
  656. }
  657. void
  658. seccomp_sandbox_lockdown()
  659. {
  660. }
  661. #endif /* __linux__ && __x86_64__ */