sandbox.c 24 KB

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