sandbox.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2013, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file sandbox.c
  8. * \brief Code to enable sandboxing.
  9. **/
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include "sandbox.h"
  14. #include "torlog.h"
  15. #include "orconfig.h"
  16. #include "torint.h"
  17. #include "util.h"
  18. #if defined(HAVE_SECCOMP_H) && defined(__linux__)
  19. #define USE_LIBSECCOMP
  20. #endif
  21. #define DEBUGGING_CLOSE
  22. #if defined(USE_LIBSECCOMP)
  23. #define _GNU_SOURCE
  24. #include <sys/mman.h>
  25. #include <sys/syscall.h>
  26. #include <sys/types.h>
  27. #include <sys/epoll.h>
  28. #include <sys/prctl.h>
  29. #include <linux/futex.h>
  30. #include <bits/signum.h>
  31. #include <stdarg.h>
  32. #include <seccomp.h>
  33. #include <signal.h>
  34. #include <unistd.h>
  35. #include <fcntl.h>
  36. #include <time.h>
  37. #include <poll.h>
  38. static sandbox_cfg_t *filter_dynamic = NULL;
  39. /** Variable used for storing all syscall numbers that will be allowed with the
  40. * stage 1 general Tor sandbox.
  41. */
  42. static int filter_nopar_gen[] = {
  43. SCMP_SYS(access),
  44. SCMP_SYS(brk),
  45. SCMP_SYS(close),
  46. SCMP_SYS(clone),
  47. SCMP_SYS(epoll_create),
  48. SCMP_SYS(epoll_wait),
  49. SCMP_SYS(fcntl),
  50. SCMP_SYS(fstat),
  51. #ifdef __NR_fstat64
  52. SCMP_SYS(fstat64),
  53. #endif
  54. SCMP_SYS(getdents64),
  55. SCMP_SYS(getegid),
  56. #ifdef __NR_getegid32
  57. SCMP_SYS(getegid32),
  58. #endif
  59. SCMP_SYS(geteuid),
  60. #ifdef __NR_geteuid32
  61. SCMP_SYS(geteuid32),
  62. #endif
  63. SCMP_SYS(getgid),
  64. #ifdef __NR_getgid32
  65. SCMP_SYS(getgid32),
  66. #endif
  67. SCMP_SYS(getrlimit),
  68. SCMP_SYS(gettimeofday),
  69. SCMP_SYS(getuid),
  70. #ifdef __NR_getuid32
  71. SCMP_SYS(getuid32),
  72. #endif
  73. SCMP_SYS(lseek),
  74. #ifdef __NR__llseek
  75. SCMP_SYS(_llseek),
  76. #endif
  77. SCMP_SYS(mkdir),
  78. SCMP_SYS(mlockall),
  79. SCMP_SYS(mmap),
  80. SCMP_SYS(munmap),
  81. SCMP_SYS(read),
  82. SCMP_SYS(rename),
  83. SCMP_SYS(rt_sigreturn),
  84. SCMP_SYS(set_robust_list),
  85. #ifdef __NR_sigreturn
  86. SCMP_SYS(sigreturn),
  87. #endif
  88. SCMP_SYS(stat),
  89. #ifdef __NR_stat64
  90. SCMP_SYS(stat64), // TODO
  91. #endif
  92. SCMP_SYS(uname),
  93. SCMP_SYS(write),
  94. SCMP_SYS(exit_group),
  95. SCMP_SYS(exit),
  96. SCMP_SYS(madvise),
  97. // Not needed..
  98. // SCMP_SYS(set_thread_area),
  99. // SCMP_SYS(set_tid_address),
  100. // socket syscalls
  101. SCMP_SYS(bind),
  102. SCMP_SYS(connect),
  103. SCMP_SYS(getsockname),
  104. SCMP_SYS(getsockopt),
  105. SCMP_SYS(listen),
  106. SCMP_SYS(recv),
  107. SCMP_SYS(recvmsg),
  108. SCMP_SYS(sendto),
  109. SCMP_SYS(send),
  110. SCMP_SYS(setsockopt),
  111. SCMP_SYS(socket),
  112. SCMP_SYS(socketpair),
  113. SCMP_SYS(recvfrom),
  114. SCMP_SYS(unlink),
  115. };
  116. static int
  117. sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  118. {
  119. int i, rc;
  120. int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD,
  121. #ifdef SIGXFSZ
  122. SIGXFSZ
  123. #endif
  124. };
  125. for (i = 0; i < ARRAY_LENGTH(param); i++) {
  126. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 1,
  127. SCMP_CMP(0, SCMP_CMP_EQ, param[i]));
  128. if (rc)
  129. break;
  130. }
  131. return rc;
  132. }
  133. static int
  134. sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  135. {
  136. int rc;
  137. sandbox_cfg_t *elem = NULL;
  138. // for each dynamic parameter filters
  139. for (elem = filter; elem != NULL; elem = elem->next) {
  140. if (elem->prot == 1 && elem->syscall == SCMP_SYS(execve)) {
  141. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1,
  142. SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
  143. if (rc != 0) {
  144. log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received libseccomp "
  145. "error %d", rc);
  146. return rc;
  147. }
  148. }
  149. }
  150. return 0;
  151. }
  152. static int
  153. sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  154. {
  155. return seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time), 1,
  156. SCMP_CMP(0, SCMP_CMP_EQ, 0));
  157. }
  158. static int
  159. sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  160. {
  161. return seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 1,
  162. SCMP_CMP(0, SCMP_CMP_EQ, 18));
  163. }
  164. #ifdef __NR_mmap2
  165. static int
  166. sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  167. {
  168. int rc = 0;
  169. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  170. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ),
  171. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE));
  172. if (rc) {
  173. return rc;
  174. }
  175. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  176. SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE),
  177. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE));
  178. if (rc) {
  179. return rc;
  180. }
  181. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  182. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
  183. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS));
  184. if (rc) {
  185. return rc;
  186. }
  187. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  188. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
  189. SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK));
  190. if (rc) {
  191. return rc;
  192. }
  193. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  194. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
  195. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE));
  196. if (rc) {
  197. return rc;
  198. }
  199. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  200. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE),
  201. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS));
  202. if (rc) {
  203. return rc;
  204. }
  205. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2,
  206. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC),
  207. SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE));
  208. if (rc) {
  209. return rc;
  210. }
  211. return 0;
  212. }
  213. #endif
  214. // TODO parameters
  215. static int
  216. sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  217. {
  218. int rc;
  219. sandbox_cfg_t *elem = NULL;
  220. // for each dynamic parameter filters
  221. for (elem = filter; elem != NULL; elem = elem->next) {
  222. if (elem->prot == 1 && elem->syscall == SCMP_SYS(open)) {
  223. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
  224. SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
  225. if (rc != 0) {
  226. log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
  227. "error %d", rc);
  228. return rc;
  229. }
  230. }
  231. }
  232. // todo remove when libevent fix
  233. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
  234. SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY));
  235. if (rc != 0) {
  236. log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
  237. "error %d", rc);
  238. return rc;
  239. }
  240. // problem: required by getaddrinfo
  241. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
  242. SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY|O_CLOEXEC));
  243. if (rc != 0) {
  244. log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
  245. "error %d", rc);
  246. return rc;
  247. }
  248. return 0;
  249. }
  250. // TODO parameters
  251. static int
  252. sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  253. {
  254. int rc;
  255. sandbox_cfg_t *elem = NULL;
  256. // for each dynamic parameter filters
  257. for (elem = filter; elem != NULL; elem = elem->next) {
  258. if (elem->prot == 1 && elem->syscall == SCMP_SYS(openat)) {
  259. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1,
  260. SCMP_CMP(1, SCMP_CMP_EQ, elem->param));
  261. if (rc != 0) {
  262. log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received libseccomp "
  263. "error %d", rc);
  264. return rc;
  265. }
  266. }
  267. }
  268. return 0;
  269. }
  270. static int
  271. sb_clock_gettime(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  272. {
  273. return seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clock_gettime), 1,
  274. SCMP_CMP(0, SCMP_CMP_EQ, CLOCK_MONOTONIC));
  275. }
  276. // TODO: param not working
  277. static int
  278. sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  279. {
  280. int rc = 0;
  281. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 4,
  282. SCMP_CMP(0, SCMP_CMP_EQ, 1),
  283. SCMP_CMP(1, SCMP_CMP_EQ, PF_INET),
  284. SCMP_CMP(2, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC),
  285. SCMP_CMP(3, SCMP_CMP_EQ, IPPROTO_TCP));
  286. if (rc)
  287. return rc;
  288. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 4,
  289. SCMP_CMP(0, SCMP_CMP_EQ, 1),
  290. SCMP_CMP(1, SCMP_CMP_EQ, PF_NETLINK),
  291. SCMP_CMP(2, SCMP_CMP_EQ, SOCK_RAW),
  292. SCMP_CMP(3, SCMP_CMP_EQ, 0));
  293. if (rc)
  294. return rc;
  295. return 0;
  296. }
  297. // TODO: param not working
  298. static int
  299. sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  300. {
  301. int rc = 0;
  302. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 2,
  303. SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET),
  304. SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR));
  305. if (rc)
  306. return rc;
  307. return 0;
  308. }
  309. #ifdef __NR_fcntl64
  310. static int
  311. sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  312. {
  313. int rc = 0;
  314. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1,
  315. SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL));
  316. if (rc)
  317. return rc;
  318. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 2,
  319. SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL),
  320. SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK));
  321. if (rc)
  322. return rc;
  323. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1,
  324. SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD));
  325. if (rc)
  326. return rc;
  327. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 2,
  328. SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD),
  329. SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC));
  330. if (rc)
  331. return rc;
  332. return 0;
  333. }
  334. #endif
  335. // allows everything but will keep for now..
  336. static int
  337. sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  338. {
  339. int rc = 0;
  340. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1,
  341. SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD));
  342. if (rc)
  343. return rc;
  344. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1,
  345. SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD));
  346. if (rc)
  347. return rc;
  348. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1,
  349. SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL));
  350. if (rc)
  351. return rc;
  352. return 0;
  353. }
  354. /**
  355. * If multiple filters need to be added, seccomp needs to be whitelisted in
  356. * this list.
  357. */
  358. static int
  359. sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  360. {
  361. int rc = 0;
  362. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1,
  363. SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE));
  364. if (rc)
  365. return rc;
  366. return 0;
  367. }
  368. /**
  369. * does not NEED tobe here.. only occurs before filter
  370. */
  371. static int
  372. sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  373. {
  374. int rc = 0;
  375. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1,
  376. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ));
  377. if (rc)
  378. return rc;
  379. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1,
  380. SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
  381. if (rc)
  382. return rc;
  383. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1,
  384. SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE));
  385. if (rc)
  386. return rc;
  387. return 0;
  388. }
  389. static int
  390. sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  391. {
  392. int rc = 0;
  393. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1,
  394. SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK));
  395. if (rc)
  396. return rc;
  397. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1,
  398. SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK));
  399. if (rc)
  400. return rc;
  401. return 0;
  402. }
  403. /**
  404. * does not NEED tobe here.. only occurs before filter
  405. */
  406. static int
  407. sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  408. {
  409. int rc = 0;
  410. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock), 1,
  411. SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB));
  412. if (rc)
  413. return rc;
  414. return 0;
  415. }
  416. static int
  417. sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  418. {
  419. int rc = 0;
  420. // can remove
  421. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1,
  422. SCMP_CMP(1, SCMP_CMP_EQ,
  423. FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME));
  424. if (rc)
  425. return rc;
  426. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1,
  427. SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
  428. if (rc)
  429. return rc;
  430. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1,
  431. SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE));
  432. if (rc)
  433. return rc;
  434. return 0;
  435. }
  436. /**
  437. * does not NEED tobe here.. only occurs before filter
  438. */
  439. static int
  440. sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  441. {
  442. int rc = 0;
  443. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 1,
  444. SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE));
  445. if (rc)
  446. return rc;
  447. return 0;
  448. }
  449. static int
  450. sb_poll(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
  451. {
  452. int rc = 0;
  453. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(poll), 2,
  454. SCMP_CMP(1, SCMP_CMP_EQ, 1),
  455. SCMP_CMP(2, SCMP_CMP_EQ, 10));
  456. if (rc)
  457. return rc;
  458. return 0;
  459. }
  460. static sandbox_filter_func_t filter_func[] = {
  461. sb_rt_sigaction,
  462. sb_rt_sigprocmask,
  463. sb_execve,
  464. sb_time,
  465. sb_accept4,
  466. sb_mmap2,
  467. sb_open,
  468. sb_openat,
  469. sb_clock_gettime,
  470. sb_fcntl64,
  471. sb_epoll_ctl,
  472. sb_prctl,
  473. sb_mprotect,
  474. sb_flock,
  475. sb_futex,
  476. sb_mremap,
  477. sb_poll
  478. };
  479. const char*
  480. sandbox_intern_string(const char *param)
  481. {
  482. sandbox_cfg_t *elem;
  483. if (param == NULL)
  484. return NULL;
  485. for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
  486. if (elem->prot && elem->ptype == PARAM_PTR
  487. && !strncmp(param, (char*)(elem->param), MAX_PARAM_LEN)) {
  488. return (char*)(elem->param);
  489. }
  490. }
  491. log_warn(LD_BUG, "(Sandbox) Parameter %s not found", param);
  492. return param;
  493. }
  494. static char*
  495. prot_strdup(char* str)
  496. {
  497. int param_size = 0;
  498. char *res = NULL;
  499. if (str == NULL)
  500. goto out;
  501. // allocating protected memory region for parameter
  502. param_size = 1 + strnlen(str, MAX_PARAM_LEN);
  503. if (param_size == MAX_PARAM_LEN) {
  504. log_warn(LD_BUG, "(Sandbox) Parameter length too large!");
  505. }
  506. res = (char*) mmap(NULL, param_size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
  507. MAP_ANON, -1, 0);
  508. if (!res) {
  509. log_err(LD_BUG,"(Sandbox) failed allocate protected memory!");
  510. goto out;
  511. }
  512. // copying from non protected to protected + pointer reassign
  513. memcpy(res, str, param_size);
  514. // protecting from writes
  515. if (mprotect(res, param_size, PROT_READ)) {
  516. log_err(LD_BUG,"(Sandbox) failed to protect memory!");
  517. return NULL;
  518. }
  519. out:
  520. return res;
  521. }
  522. int
  523. sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file, char fr)
  524. {
  525. sandbox_cfg_t *elem = NULL;
  526. elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
  527. elem->syscall = SCMP_SYS(open);
  528. elem->pindex = 0;
  529. elem->ptype = PARAM_PTR;
  530. elem->param = (intptr_t) prot_strdup((char*) file);
  531. elem->prot = 1;
  532. elem->next = *cfg;
  533. *cfg = elem;
  534. if (fr) tor_free_(file);
  535. return 0;
  536. }
  537. int
  538. sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, int num, ...)
  539. {
  540. int rc = 0, i;
  541. va_list ap;
  542. va_start(ap, num);
  543. for (i = 0; i < num; i++) {
  544. char *fn = va_arg(ap, char*);
  545. char fr = (char) va_arg(ap, int);
  546. rc = sandbox_cfg_allow_open_filename(cfg, fn, fr);
  547. if(rc) {
  548. log_err(LD_BUG,"(Sandbox) failed on par %d", i);
  549. goto end;
  550. }
  551. }
  552. end:
  553. va_end(ap);
  554. return 0;
  555. }
  556. int
  557. sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file, char fr)
  558. {
  559. sandbox_cfg_t *elem = NULL;
  560. elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
  561. elem->syscall = SCMP_SYS(openat);
  562. elem->pindex = 1;
  563. elem->ptype = PARAM_PTR;
  564. elem->param = (intptr_t) prot_strdup((char*) file);;
  565. elem->prot = 1;
  566. elem->next = *cfg;
  567. *cfg = elem;
  568. if (fr) tor_free_(file);
  569. return 0;
  570. }
  571. int
  572. sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, int num, ...)
  573. {
  574. int rc = 0, i;
  575. va_list ap;
  576. va_start(ap, num);
  577. for (i = 0; i < num; i++) {
  578. char *fn = va_arg(ap, char*);
  579. char fr = (char) va_arg(ap, int);
  580. rc = sandbox_cfg_allow_openat_filename(cfg, fn, fr);
  581. if(rc) {
  582. log_err(LD_BUG,"(Sandbox) failed on par %d", i);
  583. goto end;
  584. }
  585. }
  586. end:
  587. va_end(ap);
  588. return 0;
  589. }
  590. int
  591. sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, char *com)
  592. {
  593. sandbox_cfg_t *elem = NULL;
  594. elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
  595. elem->syscall = SCMP_SYS(openat);
  596. elem->pindex = 1;
  597. elem->ptype = PARAM_PTR;
  598. elem->param = (intptr_t) prot_strdup((char*) com);;
  599. elem->prot = 1;
  600. elem->next = *cfg;
  601. *cfg = elem;
  602. return 0;
  603. }
  604. int
  605. sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, int num, ...)
  606. {
  607. int rc = 0, i;
  608. va_list ap;
  609. va_start(ap, num);
  610. for (i = 0; i < num; i++) {
  611. char *fn = va_arg(ap, char*);
  612. rc = sandbox_cfg_allow_execve(cfg, fn);
  613. if(rc) {
  614. log_err(LD_BUG,"(Sandbox) failed on par %d", i);
  615. goto end;
  616. }
  617. }
  618. end:
  619. va_end(ap);
  620. return 0;
  621. }
  622. static int
  623. add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
  624. {
  625. int i, rc = 0;
  626. // function pointer
  627. for (i = 0; i < ARRAY_LENGTH(filter_func); i++) {
  628. if ((filter_func[i])(ctx, cfg)) {
  629. log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp "
  630. "error %d", i, rc);
  631. return rc;
  632. }
  633. }
  634. return 0;
  635. }
  636. static int
  637. add_noparam_filter(scmp_filter_ctx ctx)
  638. {
  639. int i, rc = 0;
  640. // add general filters
  641. for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) {
  642. rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i], 0);
  643. if (rc != 0) {
  644. log_err(LD_BUG,"(Sandbox) failed to add syscall index %d, "
  645. "received libseccomp error %d", i, rc);
  646. return rc;
  647. }
  648. }
  649. return 0;
  650. }
  651. /**
  652. * Function responsible for setting up and enabling a global syscall filter.
  653. * The function is a prototype developed for stage 1 of sandboxing Tor.
  654. * Returns 0 on success.
  655. */
  656. static int
  657. install_syscall_filter(sandbox_cfg_t* cfg)
  658. {
  659. int rc = 0;
  660. scmp_filter_ctx ctx;
  661. ctx = seccomp_init(SCMP_ACT_TRAP);
  662. if (ctx == NULL) {
  663. log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context");
  664. rc = -1;
  665. goto end;
  666. }
  667. // add parameter filters
  668. if ((rc = add_param_filter(ctx, cfg))) {
  669. log_err(LD_BUG, "(Sandbox) failed to add param filters!");
  670. goto end;
  671. }
  672. // adding filters with no parameters
  673. if ((rc = add_noparam_filter(ctx))) {
  674. log_err(LD_BUG, "(Sandbox) failed to add param filters!");
  675. goto end;
  676. }
  677. rc = seccomp_load(ctx);
  678. end:
  679. seccomp_release(ctx);
  680. return (rc < 0 ? -rc : rc);
  681. }
  682. /** Additional file descriptor to use when logging seccomp2 failures */
  683. static int sigsys_debugging_fd = -1;
  684. /** Use the file descriptor <b>fd</b> to log seccomp2 failures. */
  685. static void
  686. sigsys_set_debugging_fd(int fd)
  687. {
  688. sigsys_debugging_fd = fd;
  689. }
  690. /**
  691. * Function called when a SIGSYS is caught by the application. It notifies the
  692. * user that an error has occurred and either terminates or allows the
  693. * application to continue execution, based on the DEBUGGING_CLOSE symbol.
  694. */
  695. static void
  696. sigsys_debugging(int nr, siginfo_t *info, void *void_context)
  697. {
  698. ucontext_t *ctx = (ucontext_t *) (void_context);
  699. char message[64];
  700. int rv = 0, syscall, length, err;
  701. (void) nr;
  702. if (info->si_code != SYS_SECCOMP)
  703. return;
  704. if (!ctx)
  705. return;
  706. syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
  707. /* XXXX Avoid use of snprintf; it isn't on the list of Stuff You're Allowed
  708. * To Do In A Signal Handler. */
  709. length = snprintf(message, sizeof(message),
  710. "\n\n(Sandbox) bad syscall (%d) was caught.\n",
  711. syscall);
  712. err = 0;
  713. if (sigsys_debugging_fd >= 0) {
  714. rv = write(sigsys_debugging_fd, message, length);
  715. err += rv != length;
  716. }
  717. rv = write(STDOUT_FILENO, message, length);
  718. err += rv != length;
  719. if (err)
  720. _exit(2);
  721. #if defined(DEBUGGING_CLOSE)
  722. _exit(1);
  723. #endif // DEBUGGING_CLOSE
  724. }
  725. /**
  726. * Function that adds a handler for SIGSYS, which is the signal thrown
  727. * when the application is issuing a syscall which is not allowed. The
  728. * main purpose of this function is to help with debugging by identifying
  729. * filtered syscalls.
  730. */
  731. static int
  732. install_sigsys_debugging(void)
  733. {
  734. struct sigaction act;
  735. sigset_t mask;
  736. memset(&act, 0, sizeof(act));
  737. sigemptyset(&mask);
  738. sigaddset(&mask, SIGSYS);
  739. act.sa_sigaction = &sigsys_debugging;
  740. act.sa_flags = SA_SIGINFO;
  741. if (sigaction(SIGSYS, &act, NULL) < 0) {
  742. log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler");
  743. return -1;
  744. }
  745. if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
  746. log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()");
  747. return -2;
  748. }
  749. return 0;
  750. }
  751. static int register_cfg(sandbox_cfg_t* cfg) {
  752. sandbox_cfg_t *elem = NULL;
  753. if (filter_dynamic == NULL) {
  754. filter_dynamic = cfg;
  755. return 0;
  756. }
  757. for (elem = filter_dynamic; elem->next != NULL; elem = elem->next);
  758. elem->next = cfg;
  759. return 0;
  760. }
  761. #endif // USE_LIBSECCOMP
  762. #ifdef USE_LIBSECCOMP
  763. /**
  764. * Initialises the syscall sandbox filter for any linux architecture, taking
  765. * into account various available features for different linux flavours.
  766. */
  767. static int
  768. initialise_libseccomp_sandbox(sandbox_cfg_t* cfg)
  769. {
  770. if (install_sigsys_debugging())
  771. return -1;
  772. if (install_syscall_filter(cfg))
  773. return -2;
  774. if (register_cfg(cfg))
  775. return -3;
  776. return 0;
  777. }
  778. #endif // USE_LIBSECCOMP
  779. sandbox_cfg_t*
  780. sandbox_cfg_new()
  781. {
  782. return NULL;
  783. }
  784. int
  785. sandbox_init(sandbox_cfg_t* cfg)
  786. {
  787. #if defined(USE_LIBSECCOMP)
  788. return initialise_libseccomp_sandbox(cfg);
  789. #elif defined(_WIN32)
  790. log_warn(LD_BUG,"Windows sandboxing is not implemented. The feature is "
  791. "currently disabled.");
  792. return 0;
  793. #elif defined(TARGET_OS_MAC)
  794. log_warn(LD_BUG,"Mac OSX sandboxing is not implemented. The feature is "
  795. "currently disabled");
  796. return 0;
  797. #else
  798. log_warn(LD_BUG,"Sandboxing is not implemented for your platform. The "
  799. "feature is currently disabled");
  800. return 0;
  801. #endif
  802. }
  803. /**
  804. * Enables the stage 1 general sandbox. It applies a syscall filter which does
  805. * not restrict any Tor features. The filter is representative for the whole
  806. * application.
  807. */
  808. int
  809. tor_global_sandbox(void)
  810. {
  811. #if defined(USE_LIBSECCOMP)
  812. return initialise_libseccomp_sandbox(NULL);
  813. #elif defined(_WIN32)
  814. log_warn(LD_BUG,"Windows sandboxing is not implemented. The feature is "
  815. "currently disabled.");
  816. return 0;
  817. #elif defined(TARGET_OS_MAC)
  818. log_warn(LD_BUG,"Mac OSX sandboxing is not implemented. The feature is "
  819. "currently disabled");
  820. return 0;
  821. #else
  822. log_warn(LD_BUG,"Sandboxing is not implemented for your platform. The "
  823. "feature is currently disabled");
  824. return 0;
  825. #endif
  826. }
  827. /** Use <b>fd</b> to log non-survivable sandbox violations. */
  828. void
  829. sandbox_set_debugging_fd(int fd)
  830. {
  831. #ifdef USE_LIBSECCOMP
  832. sigsys_set_debugging_fd(fd);
  833. #else
  834. (void)fd;
  835. #endif
  836. }