sandbox.c (60974B)
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-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * \file sandbox.c 9 * \brief Code to enable sandboxing. 10 **/ 11 12 #include "orconfig.h" 13 14 #ifndef _LARGEFILE64_SOURCE 15 /** 16 * Temporarily required for O_LARGEFILE flag. Needs to be removed 17 * with the libevent fix. 18 */ 19 #define _LARGEFILE64_SOURCE 20 #endif /* !defined(_LARGEFILE64_SOURCE) */ 21 22 /** Malloc mprotect limit in bytes. 23 * 24 * 28/06/2017: This value was increased from 16 MB to 20 MB after we introduced 25 * LZMA support in Tor (0.3.1.1-alpha). We limit our LZMA coder to 16 MB, but 26 * liblzma has a small overhead that we need to compensate for to avoid being 27 * killed by the sandbox. 28 */ 29 #define MALLOC_MP_LIM (20*1024*1024) 30 31 #include <stdio.h> 32 #include <string.h> 33 #include <stdlib.h> 34 #include <errno.h> 35 36 #include "lib/sandbox/sandbox.h" 37 #include "lib/container/map.h" 38 #include "lib/err/torerr.h" 39 #include "lib/log/log.h" 40 #include "lib/cc/torint.h" 41 #include "lib/malloc/malloc.h" 42 #include "lib/string/scanf.h" 43 44 #include "ext/tor_queue.h" 45 #include "ext/ht.h" 46 #include "ext/siphash.h" 47 48 #define DEBUGGING_CLOSE 49 50 #if defined(USE_LIBSECCOMP) 51 52 #include <sys/mman.h> 53 #include <sys/syscall.h> 54 #include <sys/types.h> 55 #include <sys/stat.h> 56 #include <sys/epoll.h> 57 #include <sys/prctl.h> 58 #include <linux/futex.h> 59 #include <sys/file.h> 60 61 #ifdef ENABLE_FRAGILE_HARDENING 62 #include <sys/ptrace.h> 63 #endif 64 65 #include <stdarg.h> 66 #include <seccomp.h> 67 #include <signal.h> 68 #include <unistd.h> 69 #include <fcntl.h> 70 #include <time.h> 71 #include <poll.h> 72 73 #ifdef HAVE_GNU_LIBC_VERSION_H 74 #include <gnu/libc-version.h> 75 #endif 76 #ifdef HAVE_LINUX_NETFILTER_IPV4_H 77 #include <linux/netfilter_ipv4.h> 78 #endif 79 #ifdef HAVE_LINUX_IF_H 80 #include <linux/if.h> 81 #endif 82 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H 83 #include <linux/netfilter_ipv6/ip6_tables.h> 84 #endif 85 86 #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ 87 defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) 88 #define USE_BACKTRACE 89 #define BACKTRACE_PRIVATE 90 #include "lib/err/backtrace.h" 91 #endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */ 92 93 #ifdef USE_BACKTRACE 94 #include <execinfo.h> 95 #endif 96 97 /** 98 * Linux 32 bit definitions 99 */ 100 #if defined(__i386__) 101 102 #define REG_SYSCALL REG_EAX 103 #define M_SYSCALL gregs[REG_SYSCALL] 104 105 /** 106 * Linux 64 bit definitions 107 */ 108 #elif defined(__x86_64__) 109 110 #define REG_SYSCALL REG_RAX 111 #define M_SYSCALL gregs[REG_SYSCALL] 112 113 #elif defined(__arm__) 114 115 #define M_SYSCALL arm_r7 116 117 #elif defined(__aarch64__) && defined(__LP64__) 118 119 #define REG_SYSCALL 8 120 #define M_SYSCALL regs[REG_SYSCALL] 121 122 #endif /* defined(__i386__) || ... */ 123 124 #ifdef M_SYSCALL 125 #define SYSCALL_NAME_DEBUGGING 126 #endif 127 128 /** 129 * On newer architectures Linux provides a standardized, generic set of system 130 * calls (defined in Linux's include/uapi/asm-generic/unistd.h), which omits a 131 * number of legacy calls used by glibc on other platforms. 132 */ 133 #if defined(__aarch64__) || defined(__riscv) 134 #define ARCH_USES_GENERIC_SYSCALLS 135 #endif 136 137 /**Determines if at least one sandbox is active.*/ 138 static int sandbox_active = 0; 139 /** Holds the parameter list configuration for the sandbox.*/ 140 static sandbox_cfg_t *filter_dynamic = NULL; 141 142 #undef SCMP_CMP 143 #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0}) 144 #define SCMP_CMP_STR(a,b,c) \ 145 ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0}) 146 #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)}) 147 /* We use a wrapper here because these masked comparisons seem to be pretty 148 * verbose. Also, it's important to cast to scmp_datum_t before negating the 149 * mask, since otherwise the negation might get applied to a 32 bit value, and 150 * the high bits of the value might get masked out improperly. */ 151 #define SCMP_CMP_MASKED(a,b,c) \ 152 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, ~(scmp_datum_t)(b), (c)) 153 /* Negative constants aren't consistently sign extended or zero extended. 154 * Different compilers, libc, and architectures behave differently. For cases 155 * where the kernel ABI uses a 32 bit integer, this macro can be used to 156 * mask-compare only the lower 32 bits of the value. */ 157 #define SCMP_CMP_LOWER32_EQ(a,b) \ 158 SCMP_CMP4((a), SCMP_CMP_MASKED_EQ, 0xFFFFFFFF, (unsigned int)(b)) 159 160 /** Variable used for storing all syscall numbers that will be allowed with the 161 * stage 1 general Tor sandbox. 162 */ 163 static int filter_nopar_gen[] = { 164 SCMP_SYS(access), 165 SCMP_SYS(brk), 166 #ifdef __NR_clock_gettime64 167 SCMP_SYS(clock_gettime64), 168 #else 169 SCMP_SYS(clock_gettime), 170 #endif 171 SCMP_SYS(close), 172 SCMP_SYS(clone), 173 SCMP_SYS(dup), 174 #ifdef __NR_clone3 175 SCMP_SYS(clone3), 176 #endif 177 SCMP_SYS(epoll_create), 178 SCMP_SYS(epoll_wait), 179 #ifdef __NR_epoll_pwait 180 SCMP_SYS(epoll_pwait), 181 #endif 182 #ifdef HAVE_EVENTFD 183 SCMP_SYS(eventfd2), 184 #endif 185 #ifdef HAVE_PIPE2 186 SCMP_SYS(pipe2), 187 #endif 188 #ifdef HAVE_PIPE 189 SCMP_SYS(pipe), 190 #endif 191 #ifdef __NR_fchmod 192 SCMP_SYS(fchmod), 193 #endif 194 SCMP_SYS(fcntl), 195 SCMP_SYS(fstat), 196 #ifdef __NR_fstat64 197 SCMP_SYS(fstat64), 198 #endif 199 SCMP_SYS(fsync), 200 SCMP_SYS(futex), 201 SCMP_SYS(getdents), 202 SCMP_SYS(getdents64), 203 SCMP_SYS(getegid), 204 #ifdef __NR_getegid32 205 SCMP_SYS(getegid32), 206 #endif 207 SCMP_SYS(geteuid), 208 #ifdef __NR_geteuid32 209 SCMP_SYS(geteuid32), 210 #endif 211 SCMP_SYS(getgid), 212 #ifdef __NR_getgid32 213 SCMP_SYS(getgid32), 214 #endif 215 SCMP_SYS(getpid), 216 #ifdef ENABLE_FRAGILE_HARDENING 217 SCMP_SYS(getppid), 218 #endif 219 #ifdef __NR_getrlimit 220 SCMP_SYS(getrlimit), 221 #endif 222 SCMP_SYS(gettimeofday), 223 SCMP_SYS(gettid), 224 SCMP_SYS(getuid), 225 #ifdef __NR_getuid32 226 SCMP_SYS(getuid32), 227 #endif 228 SCMP_SYS(lseek), 229 #ifdef __NR__llseek 230 SCMP_SYS(_llseek), 231 #endif 232 // glob uses this.. 233 SCMP_SYS(lstat), 234 #ifdef __NR_membarrier 235 /* Inter-processor synchronization, needed for tracing support */ 236 SCMP_SYS(membarrier), 237 #endif 238 SCMP_SYS(mkdir), 239 SCMP_SYS(mlockall), 240 #ifdef __NR_mmap 241 /* XXXX restrict this in the same ways as mmap2 */ 242 SCMP_SYS(mmap), 243 #endif 244 SCMP_SYS(munmap), 245 #ifdef __NR_nanosleep 246 SCMP_SYS(nanosleep), 247 #endif 248 #ifdef __NR_prlimit 249 SCMP_SYS(prlimit), 250 #endif 251 #ifdef __NR_prlimit64 252 SCMP_SYS(prlimit64), 253 #endif 254 SCMP_SYS(read), 255 SCMP_SYS(rt_sigreturn), 256 #ifdef __NR_rseq 257 SCMP_SYS(rseq), 258 #endif 259 SCMP_SYS(sched_getaffinity), 260 #ifdef __NR_sched_yield 261 SCMP_SYS(sched_yield), 262 #endif 263 SCMP_SYS(sendmsg), 264 SCMP_SYS(set_robust_list), 265 #ifdef __NR_setrlimit 266 SCMP_SYS(setrlimit), 267 #endif 268 SCMP_SYS(shutdown), 269 #ifdef __NR_sigaltstack 270 SCMP_SYS(sigaltstack), 271 #endif 272 #ifdef __NR_sigreturn 273 SCMP_SYS(sigreturn), 274 #endif 275 #if defined(__NR_stat) 276 SCMP_SYS(stat), 277 #elif defined(__i386__) && defined(__NR_statx) 278 SCMP_SYS(statx), 279 #endif 280 SCMP_SYS(uname), 281 SCMP_SYS(wait4), 282 SCMP_SYS(write), 283 SCMP_SYS(writev), 284 SCMP_SYS(exit_group), 285 SCMP_SYS(exit), 286 287 SCMP_SYS(madvise), 288 #ifdef __NR_stat64 289 // getaddrinfo uses this.. 290 SCMP_SYS(stat64), 291 #endif 292 #ifdef __NR_lstat64 293 // glob uses this on i386 with glibc 2.36+ 294 SCMP_SYS(lstat64), 295 #endif 296 297 #ifdef __NR_getrandom 298 SCMP_SYS(getrandom), 299 #endif 300 301 #ifdef __NR_sysinfo 302 // qsort uses this.. 303 SCMP_SYS(sysinfo), 304 #endif 305 /* 306 * These socket syscalls are not required on x86_64 and not supported with 307 * some libseccomp versions (eg: 1.0.1) 308 */ 309 #if defined(__i386) 310 SCMP_SYS(recv), 311 SCMP_SYS(send), 312 #endif 313 314 // socket syscalls 315 SCMP_SYS(bind), 316 SCMP_SYS(listen), 317 SCMP_SYS(connect), 318 SCMP_SYS(getsockname), 319 #ifdef ENABLE_NSS 320 #ifdef __NR_getpeername 321 SCMP_SYS(getpeername), 322 #endif 323 #endif 324 SCMP_SYS(recvmsg), 325 SCMP_SYS(recvfrom), 326 SCMP_SYS(sendto), 327 SCMP_SYS(unlink), 328 #ifdef __NR_unlinkat 329 SCMP_SYS(unlinkat), 330 #endif 331 SCMP_SYS(poll) 332 }; 333 334 /* opendir is not a syscall but it will use either open or openat. We do not 335 * want the decision to allow open/openat to be the callers responsibility, so 336 * we create a phony syscall number for opendir and sb_opendir will choose the 337 * correct syscall. */ 338 #define PHONY_OPENDIR_SYSCALL -2 339 340 /* These macros help avoid the error where the number of filters we add on a 341 * single rule don't match the arg_cnt param. */ 342 #define seccomp_rule_add_0(ctx,act,call) \ 343 seccomp_rule_add((ctx),(act),(call),0) 344 #define seccomp_rule_add_1(ctx,act,call,f1) \ 345 seccomp_rule_add((ctx),(act),(call),1,(f1)) 346 #define seccomp_rule_add_2(ctx,act,call,f1,f2) \ 347 seccomp_rule_add((ctx),(act),(call),2,(f1),(f2)) 348 #define seccomp_rule_add_3(ctx,act,call,f1,f2,f3) \ 349 seccomp_rule_add((ctx),(act),(call),3,(f1),(f2),(f3)) 350 #define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \ 351 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4)) 352 #define seccomp_rule_add_5(ctx,act,call,f1,f2,f3,f4,f5) \ 353 seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4),(f5)) 354 355 static const char *sandbox_get_interned_string(const char *str); 356 357 /** 358 * Function responsible for setting up the rt_sigaction syscall for 359 * the seccomp filter sandbox. 360 */ 361 static int 362 sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 363 { 364 unsigned i; 365 int rc; 366 int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD, 367 SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO, 368 #ifdef SIGXFSZ 369 SIGXFSZ 370 #endif 371 }; 372 (void) filter; 373 374 for (i = 0; i < ARRAY_LENGTH(param); i++) { 375 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 376 SCMP_CMP(0, SCMP_CMP_EQ, param[i])); 377 if (rc) 378 break; 379 } 380 381 return rc; 382 } 383 384 #ifdef __NR_time 385 /** 386 * Function responsible for setting up the time syscall for 387 * the seccomp filter sandbox. 388 */ 389 static int 390 sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 391 { 392 (void) filter; 393 394 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time), 395 SCMP_CMP(0, SCMP_CMP_EQ, 0)); 396 } 397 #endif /* defined(__NR_time) */ 398 399 /** 400 * Function responsible for setting up the accept4 syscall for 401 * the seccomp filter sandbox. 402 */ 403 static int 404 sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 405 { 406 int rc = 0; 407 (void)filter; 408 409 #ifdef __i386__ 410 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 411 SCMP_CMP(0, SCMP_CMP_EQ, 18)); 412 if (rc) { 413 return rc; 414 } 415 #endif /* defined(__i386__) */ 416 417 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 418 SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0)); 419 if (rc) { 420 return rc; 421 } 422 423 return 0; 424 } 425 426 #ifdef __NR_mmap2 427 /** 428 * Function responsible for setting up the mmap2 syscall for 429 * the seccomp filter sandbox. 430 */ 431 static int 432 sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 433 { 434 int rc = 0; 435 (void)filter; 436 437 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 438 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ), 439 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE)); 440 if (rc) { 441 return rc; 442 } 443 444 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 445 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE), 446 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE)); 447 if (rc) { 448 return rc; 449 } 450 451 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 452 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), 453 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS)); 454 if (rc) { 455 return rc; 456 } 457 458 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 459 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), 460 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK)); 461 if (rc) { 462 return rc; 463 } 464 465 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 466 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE), 467 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK)); 468 if (rc) { 469 return rc; 470 } 471 472 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 473 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), 474 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE)); 475 if (rc) { 476 return rc; 477 } 478 479 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 480 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), 481 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS)); 482 if (rc) { 483 return rc; 484 } 485 486 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 487 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC), 488 SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE)); 489 if (rc) { 490 return rc; 491 } 492 493 return 0; 494 } 495 #endif /* defined(__NR_mmap2) */ 496 497 #ifdef HAVE_GNU_LIBC_VERSION_H 498 #ifdef HAVE_GNU_GET_LIBC_VERSION 499 #define CHECK_LIBC_VERSION 500 #endif 501 #endif 502 503 /* Return true the libc version is greater or equal than 504 * <b>major</b>.<b>minor</b>. Returns false otherwise. */ 505 static int 506 is_libc_at_least(int major, int minor) 507 { 508 #ifdef CHECK_LIBC_VERSION 509 const char *version = gnu_get_libc_version(); 510 if (version == NULL) 511 return 0; 512 513 int libc_major = -1; 514 int libc_minor = -1; 515 516 tor_sscanf(version, "%d.%d", &libc_major, &libc_minor); 517 if (libc_major > major) 518 return 1; 519 else if (libc_major == major && libc_minor >= minor) 520 return 1; 521 else 522 return 0; 523 #else /* !defined(CHECK_LIBC_VERSION) */ 524 (void)major; 525 (void)minor; 526 return 0; 527 #endif /* defined(CHECK_LIBC_VERSION) */ 528 } 529 530 /* Return true if we think we're running with a libc that uses openat for the 531 * open function on linux. */ 532 static int 533 libc_uses_openat_for_open(void) 534 { 535 #ifdef __NR_open 536 return is_libc_at_least(2, 26); 537 #else 538 return 1; 539 #endif /* defined(__NR_open) */ 540 } 541 542 /* Calls to opendir() cannot be filtered by the sandbox when built with fragile 543 * hardening for an architecture that uses Linux's generic syscall interface, 544 * so prevent a compiler warning by omitting this function along with 545 * sb_opendir(). */ 546 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS)) 547 /* Return true if we think we're running with a libc that uses openat for the 548 * opendir function on linux. */ 549 static int 550 libc_uses_openat_for_opendir(void) 551 { 552 #ifdef __NR_open 553 // libc 2.27 and above or between 2.15 (inclusive) and 2.22 (exclusive) 554 return is_libc_at_least(2, 27) || 555 (is_libc_at_least(2, 15) && !is_libc_at_least(2, 22)); 556 #else 557 return 1; 558 #endif /* defined(__NR_open) */ 559 } 560 #endif /* !(defined(ENABLE_FRAGILE_HARDENING) && 561 defined(ARCH_USES_GENERIC_SYSCALLS)) */ 562 563 /** Allow a single file to be opened. If <b>use_openat</b> is true, 564 * we're using a libc that remaps all the opens into openats. */ 565 static int 566 allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file) 567 { 568 if (use_openat) { 569 return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 570 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 571 SCMP_CMP_STR(1, SCMP_CMP_EQ, file)); 572 } else { 573 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 574 SCMP_CMP_STR(0, SCMP_CMP_EQ, file)); 575 } 576 } 577 578 /** 579 * Function responsible for setting up the open syscall for 580 * the seccomp filter sandbox. 581 */ 582 static int 583 sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 584 { 585 int rc; 586 sandbox_cfg_t *elem = NULL; 587 588 int use_openat = libc_uses_openat_for_open(); 589 590 #ifdef ENABLE_FRAGILE_HARDENING 591 /* AddressSanitizer uses either the "open" or the "openat" syscall (depending 592 * on the architecture) to access information about the running process via 593 * the filesystem, so the appropriate call must be allowed without 594 * restriction or the sanitizer will be unable to execute normally when the 595 * process terminates. */ 596 #ifdef ARCH_USES_GENERIC_SYSCALLS 597 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 598 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD)); 599 if (rc != 0) { 600 log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received " 601 "libseccomp error %d", rc); 602 return rc; 603 } 604 605 /* The "open" syscall is not defined on this architecture, so any other 606 * requests to open files will necessarily use "openat" as well and there is 607 * no need to consider any additional rules. */ 608 return 0; 609 #else 610 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open)); 611 if (rc != 0) { 612 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " 613 "libseccomp error %d", rc); 614 return rc; 615 } 616 617 /* If glibc also uses only the "open" syscall to open files on this system 618 * there is no need to consider any additional rules. */ 619 if (!use_openat) 620 return 0; 621 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */ 622 #endif /* defined(ENABLE_FRAGILE_HARDENING) */ 623 624 // for each dynamic parameter filters 625 for (elem = filter; elem != NULL; elem = elem->next) { 626 smp_param_t *param = elem->param; 627 628 if (param != NULL && param->prot == 1 && param->syscall 629 == SCMP_SYS(open)) { 630 rc = allow_file_open(ctx, use_openat, param->value); 631 if (rc != 0) { 632 log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " 633 "libseccomp error %d", rc); 634 return rc; 635 } 636 } 637 } 638 639 return 0; 640 } 641 642 #ifdef ARCH_USES_GENERIC_SYSCALLS 643 static int 644 sb_fchmodat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 645 { 646 int rc; 647 sandbox_cfg_t *elem = NULL; 648 649 // for each dynamic parameter filters 650 for (elem = filter; elem != NULL; elem = elem->next) { 651 smp_param_t *param = elem->param; 652 653 if (param != NULL && param->prot == 1 && param->syscall 654 == SCMP_SYS(fchmodat)) { 655 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchmodat), 656 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 657 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); 658 if (rc != 0) { 659 log_err(LD_BUG,"(Sandbox) failed to add fchmodat syscall, received " 660 "libseccomp error %d", rc); 661 return rc; 662 } 663 } 664 } 665 666 return 0; 667 } 668 #else 669 static int 670 sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 671 { 672 int rc; 673 sandbox_cfg_t *elem = NULL; 674 675 // for each dynamic parameter filters 676 for (elem = filter; elem != NULL; elem = elem->next) { 677 smp_param_t *param = elem->param; 678 679 if (param != NULL && param->prot == 1 && param->syscall 680 == SCMP_SYS(chmod)) { 681 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chmod), 682 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); 683 if (rc != 0) { 684 log_err(LD_BUG,"(Sandbox) failed to add chmod syscall, received " 685 "libseccomp error %d", rc); 686 return rc; 687 } 688 } 689 } 690 691 return 0; 692 } 693 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */ 694 695 #if defined(ARCH_USES_GENERIC_SYSCALLS) 696 static int 697 sb_fchownat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 698 { 699 int rc; 700 sandbox_cfg_t *elem = NULL; 701 702 // for each dynamic parameter filters 703 for (elem = filter; elem != NULL; elem = elem->next) { 704 smp_param_t *param = elem->param; 705 706 if (param != NULL && param->prot == 1 && param->syscall 707 == SCMP_SYS(fchownat)) { 708 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchownat), 709 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 710 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); 711 if (rc != 0) { 712 log_err(LD_BUG,"(Sandbox) failed to add fchownat syscall, received " 713 "libseccomp error %d", rc); 714 return rc; 715 } 716 } 717 } 718 719 return 0; 720 } 721 #elif defined(__i386__) 722 static int 723 sb_chown32(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 724 { 725 int rc; 726 sandbox_cfg_t *elem = NULL; 727 728 // for each dynamic parameter filters 729 for (elem = filter; elem != NULL; elem = elem->next) { 730 smp_param_t *param = elem->param; 731 732 if (param != NULL && param->prot == 1 && param->syscall 733 == SCMP_SYS(chown32)) { 734 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown32), 735 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); 736 if (rc != 0) { 737 log_err(LD_BUG,"(Sandbox) failed to add chown32 syscall, received " 738 "libseccomp error %d", rc); 739 return rc; 740 } 741 } 742 } 743 744 return 0; 745 } 746 #else 747 static int 748 sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 749 { 750 int rc; 751 sandbox_cfg_t *elem = NULL; 752 753 // for each dynamic parameter filters 754 for (elem = filter; elem != NULL; elem = elem->next) { 755 smp_param_t *param = elem->param; 756 757 if (param != NULL && param->prot == 1 && param->syscall 758 == SCMP_SYS(chown)) { 759 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown), 760 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); 761 if (rc != 0) { 762 log_err(LD_BUG,"(Sandbox) failed to add chown syscall, received " 763 "libseccomp error %d", rc); 764 return rc; 765 } 766 } 767 } 768 769 return 0; 770 } 771 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) || defined(__i386__) */ 772 773 #if defined(__NR_rename) 774 /** 775 * Function responsible for setting up the rename syscall for 776 * the seccomp filter sandbox. 777 */ 778 static int 779 sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 780 { 781 int rc; 782 sandbox_cfg_t *elem = NULL; 783 784 // for each dynamic parameter filters 785 for (elem = filter; elem != NULL; elem = elem->next) { 786 smp_param_t *param = elem->param; 787 788 if (param != NULL && param->prot == 1 && 789 param->syscall == SCMP_SYS(rename)) { 790 791 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename), 792 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value), 793 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2)); 794 if (rc != 0) { 795 log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received " 796 "libseccomp error %d", rc); 797 return rc; 798 } 799 } 800 } 801 802 return 0; 803 } 804 #elif defined(__NR_renameat) 805 /** 806 * Function responsible for setting up the renameat syscall for 807 * the seccomp filter sandbox. 808 */ 809 static int 810 sb_renameat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 811 { 812 int rc; 813 sandbox_cfg_t *elem = NULL; 814 815 // for each dynamic parameter filters 816 for (elem = filter; elem != NULL; elem = elem->next) { 817 smp_param_t *param = elem->param; 818 819 if (param != NULL && param->prot == 1 && 820 param->syscall == SCMP_SYS(renameat)) { 821 822 rc = seccomp_rule_add_4(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat), 823 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 824 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), 825 SCMP_CMP_LOWER32_EQ(2, AT_FDCWD), 826 SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2)); 827 if (rc != 0) { 828 log_err(LD_BUG,"(Sandbox) failed to add renameat syscall, received " 829 "libseccomp error %d", rc); 830 return rc; 831 } 832 } 833 } 834 835 return 0; 836 } 837 #else 838 /** 839 * Function responsible for setting up the renameat2 syscall for 840 * the seccomp filter sandbox. 841 */ 842 static int 843 sb_renameat2(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 844 { 845 int rc; 846 sandbox_cfg_t *elem = NULL; 847 848 // for each dynamic parameter filters 849 for (elem = filter; elem != NULL; elem = elem->next) { 850 smp_param_t *param = elem->param; 851 852 if (param != NULL && param->prot == 1 && 853 param->syscall == SCMP_SYS(renameat2)) { 854 855 rc = seccomp_rule_add_5(ctx, SCMP_ACT_ALLOW, SCMP_SYS(renameat2), 856 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 857 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), 858 SCMP_CMP_LOWER32_EQ(2, AT_FDCWD), 859 SCMP_CMP_STR(3, SCMP_CMP_EQ, param->value2), 860 SCMP_CMP(4, SCMP_CMP_EQ, 0)); 861 if (rc != 0) { 862 log_err(LD_BUG,"(Sandbox) failed to add renameat2 syscall, received " 863 "libseccomp error %d", rc); 864 return rc; 865 } 866 } 867 } 868 869 return 0; 870 } 871 #endif /* defined(__NR_rename) || defined(__NR_renameat) */ 872 873 /* If Tor is built with fragile hardening for an architecture that uses Linux's 874 * generic syscall interface a rule allowing the "openat" syscall without 875 * restriction will have already been added by sb_open(), so there is no need 876 * to consider adding additional, more restrictive rules here as they will 877 * simply be ignored. 878 * 879 * Also, since the "open" syscall is not defined on these architectures, glibc 880 * will necessarily use "openat" for its implementation of opendir() as well. 881 * This means neither of the following two functions will have any effect and 882 * both can be omitted. */ 883 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS)) 884 /** 885 * Function responsible for setting up the openat syscall for 886 * the seccomp filter sandbox. 887 */ 888 static int 889 sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 890 { 891 int rc; 892 sandbox_cfg_t *elem = NULL; 893 894 // for each dynamic parameter filters 895 for (elem = filter; elem != NULL; elem = elem->next) { 896 smp_param_t *param = elem->param; 897 898 if (param != NULL && param->prot == 1 && param->syscall 899 == SCMP_SYS(openat)) { 900 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 901 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 902 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), 903 SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY| 904 O_CLOEXEC)); 905 if (rc != 0) { 906 log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received " 907 "libseccomp error %d", rc); 908 return rc; 909 } 910 } 911 } 912 913 return 0; 914 } 915 916 static int 917 sb_opendir(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 918 { 919 int rc; 920 sandbox_cfg_t *elem = NULL; 921 922 // for each dynamic parameter filters 923 for (elem = filter; elem != NULL; elem = elem->next) { 924 smp_param_t *param = elem->param; 925 926 if (param != NULL && param->prot == 1 && param->syscall 927 == PHONY_OPENDIR_SYSCALL) { 928 rc = allow_file_open(ctx, libc_uses_openat_for_opendir(), param->value); 929 if (rc != 0) { 930 log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received " 931 "libseccomp error %d", rc); 932 return rc; 933 } 934 } 935 } 936 937 return 0; 938 } 939 #endif /* !(defined(ENABLE_FRAGILE_HARDENING) && 940 defined(ARCH_USES_GENERIC_SYSCALLS)) */ 941 942 #ifdef ENABLE_FRAGILE_HARDENING 943 /** 944 * Function responsible for setting up the ptrace syscall for 945 * the seccomp filter sandbox. 946 */ 947 static int 948 sb_ptrace(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 949 { 950 int rc; 951 pid_t pid = getpid(); 952 (void) filter; 953 954 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace), 955 SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_ATTACH), 956 SCMP_CMP(1, SCMP_CMP_EQ, pid)); 957 if (rc) 958 return rc; 959 960 /* AddressSanitizer uses "PTRACE_GETREGSET" on AArch64 (ARM64) and 961 * System/390, "PTRACE_GETREGS" everywhere else. */ 962 #if defined(__aarch64__) || defined(__s390__) 963 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace), 964 SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGSET), 965 SCMP_CMP(1, SCMP_CMP_EQ, pid)); 966 #else 967 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace), 968 SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGS), 969 SCMP_CMP(1, SCMP_CMP_EQ, pid)); 970 #endif /* defined(__aarch64__) || defined(__s390__) */ 971 if (rc) 972 return rc; 973 974 return 0; 975 } 976 #endif 977 978 /** 979 * Function responsible for setting up the socket syscall for 980 * the seccomp filter sandbox. 981 */ 982 static int 983 sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 984 { 985 int rc = 0; 986 int i, j; 987 (void) filter; 988 989 #ifdef __i386__ 990 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket)); 991 if (rc) 992 return rc; 993 #endif 994 995 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 996 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE), 997 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM)); 998 if (rc) 999 return rc; 1000 1001 for (i = 0; i < 2; ++i) { 1002 const int pf = i ? PF_INET : PF_INET6; 1003 for (j=0; j < 3; ++j) { 1004 const int type = (j == 0) ? SOCK_STREAM : 1005 SOCK_DGRAM; 1006 const int protocol = (j == 0) ? IPPROTO_TCP : 1007 (j == 1) ? IPPROTO_IP : 1008 IPPROTO_UDP; 1009 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1010 SCMP_CMP(0, SCMP_CMP_EQ, pf), 1011 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, type), 1012 SCMP_CMP(2, SCMP_CMP_EQ, protocol)); 1013 if (rc) 1014 return rc; 1015 } 1016 } 1017 1018 #ifdef ENABLE_NSS 1019 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1020 SCMP_CMP(0, SCMP_CMP_EQ, PF_INET), 1021 SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM), 1022 SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP)); 1023 if (rc) 1024 return rc; 1025 #endif /* defined(ENABLE_NSS) */ 1026 1027 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1028 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX), 1029 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM), 1030 SCMP_CMP(2, SCMP_CMP_EQ, 0)); 1031 if (rc) 1032 return rc; 1033 1034 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1035 SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX), 1036 SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_DGRAM), 1037 SCMP_CMP(2, SCMP_CMP_EQ, 0)); 1038 if (rc) 1039 return rc; 1040 1041 rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1042 SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK), 1043 SCMP_CMP_MASKED(1, SOCK_CLOEXEC, SOCK_RAW), 1044 SCMP_CMP(2, SCMP_CMP_EQ, 0)); 1045 if (rc) 1046 return rc; 1047 1048 return 0; 1049 } 1050 1051 /** 1052 * Function responsible for setting up the socketpair syscall for 1053 * the seccomp filter sandbox. 1054 */ 1055 static int 1056 sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1057 { 1058 int rc = 0; 1059 (void) filter; 1060 1061 #ifdef __i386__ 1062 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair)); 1063 if (rc) 1064 return rc; 1065 #endif 1066 1067 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 1068 SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE), 1069 SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC)); 1070 if (rc) 1071 return rc; 1072 1073 return 0; 1074 } 1075 1076 #ifdef HAVE_KIST_SUPPORT 1077 1078 #include <linux/sockios.h> 1079 1080 static int 1081 sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1082 { 1083 int rc; 1084 (void) filter; 1085 1086 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1087 SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD)); 1088 if (rc) 1089 return rc; 1090 return 0; 1091 } 1092 1093 #endif /* defined(HAVE_KIST_SUPPORT) */ 1094 1095 /** 1096 * Function responsible for setting up the setsockopt syscall for 1097 * the seccomp filter sandbox. 1098 */ 1099 static int 1100 sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1101 { 1102 int rc = 0; 1103 (void) filter; 1104 1105 #ifdef __i386__ 1106 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt)); 1107 if (rc) 1108 return rc; 1109 #endif 1110 1111 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1112 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1113 SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR)); 1114 if (rc) 1115 return rc; 1116 1117 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1118 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1119 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF)); 1120 if (rc) 1121 return rc; 1122 1123 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1124 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1125 SCMP_CMP(2, SCMP_CMP_EQ, SO_RCVBUF)); 1126 if (rc) 1127 return rc; 1128 1129 #ifdef HAVE_SYSTEMD 1130 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1131 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1132 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE)); 1133 if (rc) 1134 return rc; 1135 #endif /* defined(HAVE_SYSTEMD) */ 1136 1137 #ifdef IP_TRANSPARENT 1138 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1139 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), 1140 SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT)); 1141 if (rc) 1142 return rc; 1143 #endif /* defined(IP_TRANSPARENT) */ 1144 1145 #ifdef IPV6_V6ONLY 1146 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1147 SCMP_CMP(1, SCMP_CMP_EQ, IPPROTO_IPV6), 1148 SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY)); 1149 if (rc) 1150 return rc; 1151 #endif /* defined(IPV6_V6ONLY) */ 1152 1153 #ifdef IP_BIND_ADDRESS_NO_PORT 1154 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 1155 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), 1156 SCMP_CMP(2, SCMP_CMP_EQ, IP_BIND_ADDRESS_NO_PORT)); 1157 if (rc) 1158 return rc; 1159 #endif 1160 1161 return 0; 1162 } 1163 1164 /** 1165 * Function responsible for setting up the getsockopt syscall for 1166 * the seccomp filter sandbox. 1167 */ 1168 static int 1169 sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1170 { 1171 int rc = 0; 1172 (void) filter; 1173 1174 #ifdef __i386__ 1175 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt)); 1176 if (rc) 1177 return rc; 1178 #endif 1179 1180 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1181 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1182 SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR)); 1183 if (rc) 1184 return rc; 1185 1186 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1187 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1188 SCMP_CMP(2, SCMP_CMP_EQ, SO_ACCEPTCONN)); 1189 if (rc) 1190 return rc; 1191 1192 #ifdef HAVE_SYSTEMD 1193 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1194 SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), 1195 SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF)); 1196 if (rc) 1197 return rc; 1198 #endif /* defined(HAVE_SYSTEMD) */ 1199 1200 #ifdef HAVE_LINUX_NETFILTER_IPV4_H 1201 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1202 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), 1203 SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST)); 1204 if (rc) 1205 return rc; 1206 #endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */ 1207 1208 #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H 1209 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1210 SCMP_CMP(1, SCMP_CMP_EQ, SOL_IPV6), 1211 SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST)); 1212 if (rc) 1213 return rc; 1214 #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */ 1215 1216 #ifdef HAVE_KIST_SUPPORT 1217 #include <netinet/tcp.h> 1218 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 1219 SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP), 1220 SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO)); 1221 if (rc) 1222 return rc; 1223 #endif /* defined(HAVE_KIST_SUPPORT) */ 1224 1225 return 0; 1226 } 1227 1228 #ifdef __NR_fcntl64 1229 /** 1230 * Function responsible for setting up the fcntl64 syscall for 1231 * the seccomp filter sandbox. 1232 */ 1233 static int 1234 sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1235 { 1236 int rc = 0; 1237 (void) filter; 1238 1239 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1240 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL)); 1241 if (rc) 1242 return rc; 1243 1244 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1245 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL), 1246 SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK)); 1247 if (rc) 1248 return rc; 1249 1250 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1251 SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD)); 1252 if (rc) 1253 return rc; 1254 1255 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1256 SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD), 1257 SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC)); 1258 if (rc) 1259 return rc; 1260 1261 return 0; 1262 } 1263 #endif /* defined(__NR_fcntl64) */ 1264 1265 /** 1266 * Function responsible for setting up the epoll_ctl syscall for 1267 * the seccomp filter sandbox. 1268 * 1269 * Note: basically allows everything but will keep for now.. 1270 */ 1271 static int 1272 sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1273 { 1274 int rc = 0; 1275 (void) filter; 1276 1277 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1278 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD)); 1279 if (rc) 1280 return rc; 1281 1282 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1283 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD)); 1284 if (rc) 1285 return rc; 1286 1287 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1288 SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL)); 1289 if (rc) 1290 return rc; 1291 1292 return 0; 1293 } 1294 1295 /** 1296 * Function responsible for setting up the prctl syscall for 1297 * the seccomp filter sandbox. 1298 * 1299 * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs 1300 * to be allowlisted in this function. 1301 */ 1302 static int 1303 sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1304 { 1305 int rc = 0; 1306 (void) filter; 1307 1308 #ifdef ENABLE_FRAGILE_HARDENING 1309 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1310 SCMP_CMP(0, SCMP_CMP_EQ, PR_GET_DUMPABLE)); 1311 if (rc) 1312 return rc; 1313 1314 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1315 SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_PTRACER)); 1316 if (rc) 1317 return rc; 1318 #endif 1319 1320 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1321 SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE)); 1322 if (rc) 1323 return rc; 1324 1325 return 0; 1326 } 1327 1328 /** 1329 * Function responsible for setting up the mprotect syscall for 1330 * the seccomp filter sandbox. 1331 * 1332 * NOTE: does not NEED to be here.. currently only occurs before filter; will 1333 * keep just in case for the future. 1334 */ 1335 static int 1336 sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1337 { 1338 int rc = 0; 1339 (void) filter; 1340 1341 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1342 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ)); 1343 if (rc) 1344 return rc; 1345 1346 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1347 SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE)); 1348 if (rc) 1349 return rc; 1350 1351 return 0; 1352 } 1353 1354 /** 1355 * Function responsible for setting up the rt_sigprocmask syscall for 1356 * the seccomp filter sandbox. 1357 */ 1358 static int 1359 sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1360 { 1361 int rc = 0; 1362 (void) filter; 1363 1364 #if defined(ENABLE_FRAGILE_HARDENING) || \ 1365 defined(USE_TRACING_INSTRUMENTATION_LTTNG) 1366 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1367 SCMP_CMP(0, SCMP_CMP_EQ, SIG_BLOCK)); 1368 if (rc) 1369 return rc; 1370 #endif 1371 1372 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1373 SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK)); 1374 if (rc) 1375 return rc; 1376 1377 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1378 SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK)); 1379 if (rc) 1380 return rc; 1381 1382 return 0; 1383 } 1384 1385 /** 1386 * Function responsible for setting up the flock syscall for 1387 * the seccomp filter sandbox. 1388 * 1389 * NOTE: does not need to be here, occurs before filter is applied. 1390 */ 1391 static int 1392 sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1393 { 1394 int rc = 0; 1395 (void) filter; 1396 1397 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock), 1398 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB)); 1399 if (rc) 1400 return rc; 1401 1402 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock), 1403 SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN)); 1404 if (rc) 1405 return rc; 1406 1407 return 0; 1408 } 1409 1410 /** 1411 * Function responsible for setting up the futex syscall for 1412 * the seccomp filter sandbox. 1413 */ 1414 static int 1415 sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1416 { 1417 int rc = 0; 1418 (void) filter; 1419 1420 // can remove 1421 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1422 SCMP_CMP(1, SCMP_CMP_EQ, 1423 FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME)); 1424 if (rc) 1425 return rc; 1426 1427 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1428 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE)); 1429 if (rc) 1430 return rc; 1431 1432 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1433 SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE)); 1434 if (rc) 1435 return rc; 1436 1437 return 0; 1438 } 1439 1440 /** 1441 * Function responsible for setting up the mremap syscall for 1442 * the seccomp filter sandbox. 1443 * 1444 * NOTE: so far only occurs before filter is applied. 1445 */ 1446 static int 1447 sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1448 { 1449 int rc = 0; 1450 (void) filter; 1451 1452 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 1453 SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE)); 1454 if (rc) 1455 return rc; 1456 1457 return 0; 1458 } 1459 1460 #ifdef ARCH_USES_GENERIC_SYSCALLS 1461 /** 1462 * Function responsible for setting up the newfstatat syscall for 1463 * the seccomp filter sandbox. 1464 */ 1465 static int 1466 sb_newfstatat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1467 { 1468 int rc = 0; 1469 1470 sandbox_cfg_t *elem = NULL; 1471 1472 // for each dynamic parameter filters 1473 for (elem = filter; elem != NULL; elem = elem->next) { 1474 smp_param_t *param = elem->param; 1475 1476 if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open) 1477 || param->syscall == PHONY_OPENDIR_SYSCALL 1478 || param->syscall == SCMP_SYS(newfstatat))) { 1479 rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat), 1480 SCMP_CMP_LOWER32_EQ(0, AT_FDCWD), 1481 SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value)); 1482 if (rc != 0) { 1483 log_err(LD_BUG,"(Sandbox) failed to add newfstatat syscall, received " 1484 "libseccomp error %d", rc); 1485 return rc; 1486 } 1487 } 1488 } 1489 1490 return 0; 1491 } 1492 #endif /* defined(ARCH_USES_GENERIC_SYSCALLS) */ 1493 1494 #ifdef __NR_stat64 1495 /** 1496 * Function responsible for setting up the stat64 syscall for 1497 * the seccomp filter sandbox. 1498 */ 1499 static int 1500 sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1501 { 1502 int rc = 0; 1503 sandbox_cfg_t *elem = NULL; 1504 1505 // for each dynamic parameter filters 1506 for (elem = filter; elem != NULL; elem = elem->next) { 1507 smp_param_t *param = elem->param; 1508 1509 if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open) 1510 || param->syscall == SCMP_SYS(stat64))) { 1511 rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64), 1512 SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); 1513 if (rc != 0) { 1514 log_err(LD_BUG,"(Sandbox) failed to add stat64 syscall, received " 1515 "libseccomp error %d", rc); 1516 return rc; 1517 } 1518 } 1519 } 1520 1521 return 0; 1522 } 1523 #endif /* defined(__NR_stat64) */ 1524 1525 static int 1526 sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter) 1527 { 1528 (void) filter; 1529 #ifdef __NR_kill 1530 /* Allow killing anything with signal 0 -- it isn't really a kill. */ 1531 return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(kill), 1532 SCMP_CMP(1, SCMP_CMP_EQ, 0)); 1533 #else 1534 return 0; 1535 #endif /* defined(__NR_kill) */ 1536 } 1537 1538 /** 1539 * Array of function pointers responsible for filtering different syscalls at 1540 * a parameter level. 1541 */ 1542 static sandbox_filter_func_t filter_func[] = { 1543 sb_rt_sigaction, 1544 sb_rt_sigprocmask, 1545 #ifdef __NR_time 1546 sb_time, 1547 #endif 1548 sb_accept4, 1549 #ifdef __NR_mmap2 1550 sb_mmap2, 1551 #endif 1552 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1553 sb_fchownat, 1554 #elif defined(__i386__) 1555 sb_chown32, 1556 #else 1557 sb_chown, 1558 #endif 1559 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1560 sb_fchmodat, 1561 #else 1562 sb_chmod, 1563 #endif 1564 sb_open, 1565 #if !(defined(ENABLE_FRAGILE_HARDENING) && defined(ARCH_USES_GENERIC_SYSCALLS)) 1566 sb_openat, 1567 sb_opendir, 1568 #endif 1569 #ifdef ENABLE_FRAGILE_HARDENING 1570 sb_ptrace, 1571 #endif 1572 #if defined(__NR_rename) 1573 sb_rename, 1574 #elif defined(__NR_renameat) 1575 sb_renameat, 1576 #else 1577 sb_renameat2, 1578 #endif 1579 #ifdef __NR_fcntl64 1580 sb_fcntl64, 1581 #endif 1582 sb_epoll_ctl, 1583 sb_prctl, 1584 sb_mprotect, 1585 sb_flock, 1586 sb_futex, 1587 sb_mremap, 1588 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1589 sb_newfstatat, 1590 #elif defined(__NR_stat64) 1591 sb_stat64, 1592 #endif 1593 1594 sb_socket, 1595 sb_setsockopt, 1596 sb_getsockopt, 1597 sb_socketpair, 1598 #ifdef HAVE_KIST_SUPPORT 1599 sb_ioctl, 1600 #endif 1601 sb_kill 1602 }; 1603 1604 /** 1605 * Return the interned (and hopefully sandbox-permitted) string equal 1606 * to @a str. 1607 * 1608 * Return NULL if `str` is NULL, or `str` is not an interned string. 1609 **/ 1610 const char * 1611 sandbox_intern_string(const char *str) 1612 { 1613 const char *interned = sandbox_get_interned_string(str); 1614 1615 if (sandbox_active && str != NULL && interned == NULL) { 1616 log_warn(LD_BUG, "No interned sandbox parameter found for %s", str); 1617 } 1618 1619 return interned ? interned : str; 1620 } 1621 1622 /** 1623 * Return true if the sandbox is running and we are missing an interned string 1624 * equal to @a str. 1625 */ 1626 bool 1627 sandbox_interned_string_is_missing(const char *str) 1628 { 1629 return sandbox_active && sandbox_get_interned_string(str) == NULL; 1630 } 1631 1632 /** 1633 * Try to find and return the interned string equal to @a str. 1634 * 1635 * If there is no such string, return NULL. 1636 **/ 1637 static const char * 1638 sandbox_get_interned_string(const char *str) 1639 { 1640 sandbox_cfg_t *elem; 1641 1642 if (str == NULL) 1643 return NULL; 1644 1645 for (elem = filter_dynamic; elem != NULL; elem = elem->next) { 1646 smp_param_t *param = elem->param; 1647 1648 if (param->prot) { 1649 if (!strcmp(str, (char*)(param->value))) { 1650 return (char*)param->value; 1651 } 1652 if (param->value2 && !strcmp(str, (char*)param->value2)) { 1653 return (char*)param->value2; 1654 } 1655 } 1656 } 1657 1658 return NULL; 1659 } 1660 1661 /* DOCDOC */ 1662 static int 1663 prot_strings_helper(strmap_t *locations, 1664 char **pr_mem_next_p, 1665 size_t *pr_mem_left_p, 1666 char **value_p) 1667 { 1668 char *param_val; 1669 size_t param_size; 1670 void *location; 1671 1672 if (*value_p == 0) 1673 return 0; 1674 1675 param_val = (char*) *value_p; 1676 param_size = strlen(param_val) + 1; 1677 location = strmap_get(locations, param_val); 1678 1679 if (location) { 1680 // We already interned this string. 1681 tor_free(param_val); 1682 *value_p = location; 1683 return 0; 1684 } else if (*pr_mem_left_p >= param_size) { 1685 // copy to protected 1686 location = *pr_mem_next_p; 1687 memcpy(location, param_val, param_size); 1688 1689 // re-point el parameter to protected 1690 tor_free(param_val); 1691 *value_p = location; 1692 1693 strmap_set(locations, location, location); /* good real estate advice */ 1694 1695 // move next available protected memory 1696 *pr_mem_next_p += param_size; 1697 *pr_mem_left_p -= param_size; 1698 return 0; 1699 } else { 1700 log_err(LD_BUG,"(Sandbox) insufficient protected memory!"); 1701 return -1; 1702 } 1703 } 1704 1705 /** 1706 * Protects all the strings in the sandbox's parameter list configuration. It 1707 * works by calculating the total amount of memory required by the parameter 1708 * list, allocating the memory using mmap, and protecting it from writes with 1709 * mprotect(). 1710 */ 1711 static int 1712 prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) 1713 { 1714 int ret = 0; 1715 size_t pr_mem_size = 0, pr_mem_left = 0; 1716 char *pr_mem_next = NULL, *pr_mem_base; 1717 sandbox_cfg_t *el = NULL; 1718 strmap_t *locations = NULL; 1719 1720 // get total number of bytes required to mmap. (Overestimate.) 1721 for (el = cfg; el != NULL; el = el->next) { 1722 pr_mem_size += strlen((char*) el->param->value) + 1; 1723 if (el->param->value2) 1724 pr_mem_size += strlen((char*) el->param->value2) + 1; 1725 } 1726 1727 // allocate protected memory with MALLOC_MP_LIM canary 1728 pr_mem_base = (char*) mmap(NULL, MALLOC_MP_LIM + pr_mem_size, 1729 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); 1730 if (pr_mem_base == MAP_FAILED) { 1731 log_err(LD_BUG,"(Sandbox) failed allocate protected memory! mmap: %s", 1732 strerror(errno)); 1733 ret = -1; 1734 goto out; 1735 } 1736 1737 pr_mem_next = pr_mem_base + MALLOC_MP_LIM; 1738 pr_mem_left = pr_mem_size; 1739 1740 locations = strmap_new(); 1741 1742 // change el value pointer to protected 1743 for (el = cfg; el != NULL; el = el->next) { 1744 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left, 1745 &el->param->value) < 0) { 1746 ret = -2; 1747 goto out; 1748 } 1749 if (prot_strings_helper(locations, &pr_mem_next, &pr_mem_left, 1750 &el->param->value2) < 0) { 1751 ret = -2; 1752 goto out; 1753 } 1754 el->param->prot = 1; 1755 } 1756 1757 // protecting from writes 1758 if (mprotect(pr_mem_base, MALLOC_MP_LIM + pr_mem_size, PROT_READ)) { 1759 log_err(LD_BUG,"(Sandbox) failed to protect memory! mprotect: %s", 1760 strerror(errno)); 1761 ret = -3; 1762 goto out; 1763 } 1764 1765 /* 1766 * Setting sandbox restrictions so the string memory cannot be tampered with 1767 */ 1768 // no mremap of the protected base address 1769 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(mremap), 1770 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base)); 1771 if (ret) { 1772 log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!"); 1773 goto out; 1774 } 1775 1776 // no munmap of the protected base address 1777 ret = seccomp_rule_add_1(ctx, SCMP_ACT_KILL, SCMP_SYS(munmap), 1778 SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base)); 1779 if (ret) { 1780 log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!"); 1781 goto out; 1782 } 1783 1784 /* 1785 * Allow mprotect with PROT_READ|PROT_WRITE because openssl uses it, but 1786 * never over the memory region used by the protected strings. 1787 * 1788 * PROT_READ|PROT_WRITE was originally fully allowed in sb_mprotect(), but 1789 * had to be removed due to limitation of libseccomp regarding intervals. 1790 * 1791 * There is a restriction on how much you can mprotect with R|W up to the 1792 * size of the canary. 1793 */ 1794 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1795 SCMP_CMP(0, SCMP_CMP_LT, (intptr_t) pr_mem_base), 1796 SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM), 1797 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); 1798 if (ret) { 1799 log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!"); 1800 goto out; 1801 } 1802 1803 ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1804 SCMP_CMP(0, SCMP_CMP_GT, (intptr_t) pr_mem_base + pr_mem_size + 1805 MALLOC_MP_LIM), 1806 SCMP_CMP(1, SCMP_CMP_LE, MALLOC_MP_LIM), 1807 SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); 1808 if (ret) { 1809 log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!"); 1810 goto out; 1811 } 1812 1813 out: 1814 strmap_free(locations, NULL); 1815 return ret; 1816 } 1817 1818 /** 1819 * Auxiliary function used in order to allocate a sandbox_cfg_t element and set 1820 * its values according the parameter list. All elements are initialised 1821 * with the 'prot' field set to false, as the pointer is not protected at this 1822 * point. 1823 */ 1824 static sandbox_cfg_t* 1825 new_element2(int syscall, char *value, char *value2) 1826 { 1827 smp_param_t *param = NULL; 1828 1829 sandbox_cfg_t *elem = tor_malloc_zero(sizeof(sandbox_cfg_t)); 1830 param = elem->param = tor_malloc_zero(sizeof(smp_param_t)); 1831 1832 param->syscall = syscall; 1833 param->value = value; 1834 param->value2 = value2; 1835 param->prot = 0; 1836 1837 return elem; 1838 } 1839 1840 static sandbox_cfg_t* 1841 new_element(int syscall, char *value) 1842 { 1843 return new_element2(syscall, value, NULL); 1844 } 1845 1846 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1847 #define SCMP_chown SCMP_SYS(fchownat) 1848 #elif defined(__i386__) 1849 #define SCMP_chown SCMP_SYS(chown32) 1850 #else 1851 #define SCMP_chown SCMP_SYS(chown) 1852 #endif 1853 1854 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1855 #define SCMP_chmod SCMP_SYS(fchmodat) 1856 #else 1857 #define SCMP_chmod SCMP_SYS(chmod) 1858 #endif 1859 1860 #if defined(__NR_rename) 1861 #define SCMP_rename SCMP_SYS(rename) 1862 #elif defined(__NR_renameat) 1863 #define SCMP_rename SCMP_SYS(renameat) 1864 #else 1865 #define SCMP_rename SCMP_SYS(renameat2) 1866 #endif 1867 1868 #if defined(ARCH_USES_GENERIC_SYSCALLS) 1869 #define SCMP_stat SCMP_SYS(newfstatat) 1870 #elif defined(__NR_stat64) 1871 #define SCMP_stat SCMP_SYS(stat64) 1872 #else 1873 #define SCMP_stat SCMP_SYS(stat) 1874 #endif 1875 1876 int 1877 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) 1878 { 1879 sandbox_cfg_t *elem = NULL; 1880 1881 elem = new_element(SCMP_stat, file); 1882 1883 elem->next = *cfg; 1884 *cfg = elem; 1885 1886 return 0; 1887 } 1888 1889 int 1890 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file) 1891 { 1892 sandbox_cfg_t *elem = NULL; 1893 1894 elem = new_element(SCMP_SYS(open), file); 1895 1896 elem->next = *cfg; 1897 *cfg = elem; 1898 1899 return 0; 1900 } 1901 1902 int 1903 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file) 1904 { 1905 sandbox_cfg_t *elem = NULL; 1906 1907 elem = new_element(SCMP_chmod, file); 1908 1909 elem->next = *cfg; 1910 *cfg = elem; 1911 1912 return 0; 1913 } 1914 1915 int 1916 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file) 1917 { 1918 sandbox_cfg_t *elem = NULL; 1919 1920 elem = new_element(SCMP_chown, file); 1921 1922 elem->next = *cfg; 1923 *cfg = elem; 1924 1925 return 0; 1926 } 1927 1928 int 1929 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) 1930 { 1931 sandbox_cfg_t *elem = NULL; 1932 1933 elem = new_element2(SCMP_rename, file1, file2); 1934 1935 elem->next = *cfg; 1936 *cfg = elem; 1937 1938 return 0; 1939 } 1940 1941 int 1942 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) 1943 { 1944 sandbox_cfg_t *elem = NULL; 1945 1946 elem = new_element(SCMP_SYS(openat), file); 1947 1948 elem->next = *cfg; 1949 *cfg = elem; 1950 1951 return 0; 1952 } 1953 1954 int 1955 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t **cfg, char *dir) 1956 { 1957 sandbox_cfg_t *elem = NULL; 1958 1959 elem = new_element(PHONY_OPENDIR_SYSCALL, dir); 1960 1961 elem->next = *cfg; 1962 *cfg = elem; 1963 1964 return 0; 1965 } 1966 1967 /** 1968 * Function responsible for going through the parameter syscall filters and 1969 * call each function pointer in the list. 1970 */ 1971 static int 1972 add_param_filter(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) 1973 { 1974 unsigned i; 1975 int rc = 0; 1976 1977 // function pointer 1978 for (i = 0; i < ARRAY_LENGTH(filter_func); i++) { 1979 rc = filter_func[i](ctx, cfg); 1980 if (rc) { 1981 log_err(LD_BUG,"(Sandbox) failed to add syscall %d, received libseccomp " 1982 "error %d", i, rc); 1983 return rc; 1984 } 1985 } 1986 1987 return 0; 1988 } 1989 1990 /** 1991 * Function responsible of loading the libseccomp syscall filters which do not 1992 * have parameter filtering. 1993 */ 1994 static int 1995 add_noparam_filter(scmp_filter_ctx ctx) 1996 { 1997 unsigned i; 1998 int rc = 0; 1999 2000 // add general filters 2001 for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) { 2002 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i]); 2003 if (rc != 0) { 2004 log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), " 2005 "received libseccomp error %d", i, filter_nopar_gen[i], rc); 2006 return rc; 2007 } 2008 } 2009 2010 if (is_libc_at_least(2, 33)) { 2011 #ifdef __NR_newfstatat 2012 // Libc 2.33 uses this syscall to implement both fstat() and stat(). 2013 // 2014 // The trouble is that to implement fstat(fd, &st), it calls: 2015 // newfstatat(fs, "", &st, AT_EMPTY_PATH) 2016 // We can't detect this usage in particular, because "" is a pointer 2017 // we don't control. And we can't just look for AT_EMPTY_PATH, since 2018 // AT_EMPTY_PATH only has effect when the path string is empty. 2019 // 2020 // So our only solution seems to be allowing all fstatat calls, which 2021 // means that an attacker can stat() anything on the filesystem. That's 2022 // not a great solution, but I can't find a better one. 2023 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat)); 2024 if (rc != 0) { 2025 log_err(LD_BUG,"(Sandbox) failed to add newfstatat() syscall; " 2026 "received libseccomp error %d", rc); 2027 return rc; 2028 } 2029 #elif defined(__NR_fstatat64) 2030 // On i386, glibc uses fstatat64 instead of newfstatat. 2031 // This is needed for glob() and stat() operations on 32-bit systems. 2032 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstatat64)); 2033 if (rc != 0) { 2034 log_err(LD_BUG,"(Sandbox) failed to add fstatat64() syscall; " 2035 "received libseccomp error %d", rc); 2036 return rc; 2037 } 2038 #endif 2039 #if defined(__i386__) && defined(__NR_statx) 2040 // On i386 with glibc 2.33+, statx may be used for time64 support. 2041 // glob() in glibc 2.36+ uses statx for directory traversal. 2042 rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(statx)); 2043 if (rc != 0) { 2044 log_err(LD_BUG,"(Sandbox) failed to add statx() syscall; " 2045 "received libseccomp error %d", rc); 2046 return rc; 2047 } 2048 #endif 2049 } 2050 2051 return 0; 2052 } 2053 2054 /** 2055 * Function responsible for setting up and enabling a global syscall filter. 2056 * The function is a prototype developed for stage 1 of sandboxing Tor. 2057 * Returns 0 on success. 2058 */ 2059 static int 2060 install_syscall_filter(sandbox_cfg_t* cfg) 2061 { 2062 int rc = 0; 2063 scmp_filter_ctx ctx; 2064 2065 ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM)); 2066 if (ctx == NULL) { 2067 log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context"); 2068 rc = -1; 2069 goto end; 2070 } 2071 2072 // protecting sandbox parameter strings 2073 if ((rc = prot_strings(ctx, cfg))) { 2074 goto end; 2075 } 2076 2077 // add parameter filters 2078 if ((rc = add_param_filter(ctx, cfg))) { 2079 log_err(LD_BUG, "(Sandbox) failed to add param filters!"); 2080 goto end; 2081 } 2082 2083 // adding filters with no parameters 2084 if ((rc = add_noparam_filter(ctx))) { 2085 log_err(LD_BUG, "(Sandbox) failed to add param filters!"); 2086 goto end; 2087 } 2088 2089 // loading the seccomp2 filter 2090 if ((rc = seccomp_load(ctx))) { 2091 log_err(LD_BUG, "(Sandbox) failed to load: %d (%s)! " 2092 "Are you sure that your kernel has seccomp2 support? The " 2093 "sandbox won't work without it.", rc, 2094 strerror(-rc)); 2095 goto end; 2096 } 2097 2098 // marking the sandbox as active 2099 sandbox_active = 1; 2100 2101 end: 2102 seccomp_release(ctx); 2103 return (rc < 0 ? -rc : rc); 2104 } 2105 2106 #ifdef SYSCALL_NAME_DEBUGGING 2107 #include "lib/sandbox/linux_syscalls.inc" 2108 2109 /** Return a string containing the name of a given syscall (if we know it) */ 2110 static const char * 2111 get_syscall_name(int syscall_num) 2112 { 2113 int i; 2114 for (i = 0; SYSCALLS_BY_NUMBER[i].syscall_name; ++i) { 2115 if (SYSCALLS_BY_NUMBER[i].syscall_num == syscall_num) 2116 return SYSCALLS_BY_NUMBER[i].syscall_name; 2117 } 2118 2119 { 2120 static char syscall_name_buf[64]; 2121 format_dec_number_sigsafe(syscall_num, 2122 syscall_name_buf, sizeof(syscall_name_buf)); 2123 return syscall_name_buf; 2124 } 2125 } 2126 2127 /** Return the syscall number from a ucontext_t that we got in a signal 2128 * handler (if we know how to do that). */ 2129 static int 2130 get_syscall_from_ucontext(const ucontext_t *ctx) 2131 { 2132 return (int) ctx->uc_mcontext.M_SYSCALL; 2133 } 2134 #else /* !defined(SYSCALL_NAME_DEBUGGING) */ 2135 static const char * 2136 get_syscall_name(int syscall_num) 2137 { 2138 (void) syscall_num; 2139 return "unknown"; 2140 } 2141 static int 2142 get_syscall_from_ucontext(const ucontext_t *ctx) 2143 { 2144 (void) ctx; 2145 return -1; 2146 } 2147 #endif /* defined(SYSCALL_NAME_DEBUGGING) */ 2148 2149 #ifdef USE_BACKTRACE 2150 #define MAX_DEPTH 256 2151 static void *syscall_cb_buf[MAX_DEPTH]; 2152 #endif 2153 2154 /** 2155 * Function called when a SIGSYS is caught by the application. It notifies the 2156 * user that an error has occurred and either terminates or allows the 2157 * application to continue execution, based on the DEBUGGING_CLOSE symbol. 2158 */ 2159 static void 2160 sigsys_debugging(int nr, siginfo_t *info, void *void_context) 2161 { 2162 ucontext_t *ctx = (ucontext_t *) (void_context); 2163 const char *syscall_name; 2164 #ifdef USE_BACKTRACE 2165 size_t depth; 2166 int n_fds, i; 2167 const int *fds = NULL; 2168 #endif 2169 2170 (void) nr; 2171 2172 if (info->si_code != SYS_SECCOMP) 2173 return; 2174 2175 if (!ctx) 2176 return; 2177 2178 int syscall = get_syscall_from_ucontext(ctx); 2179 2180 #ifdef USE_BACKTRACE 2181 depth = backtrace(syscall_cb_buf, MAX_DEPTH); 2182 /* Clean up the top stack frame so we get the real function 2183 * name for the most recently failing function. */ 2184 clean_backtrace(syscall_cb_buf, depth, ctx); 2185 #endif /* defined(USE_BACKTRACE) */ 2186 2187 syscall_name = get_syscall_name(syscall); 2188 2189 tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ", 2190 syscall_name, 2191 ")\n", 2192 NULL); 2193 2194 #ifdef USE_BACKTRACE 2195 n_fds = tor_log_get_sigsafe_err_fds(&fds); 2196 for (i=0; i < n_fds; ++i) 2197 backtrace_symbols_fd(syscall_cb_buf, (int)depth, fds[i]); 2198 #endif 2199 2200 #if defined(DEBUGGING_CLOSE) 2201 _exit(1); // exit ok: programming error has led to sandbox failure. 2202 #endif // DEBUGGING_CLOSE 2203 } 2204 2205 /** 2206 * Function that adds a handler for SIGSYS, which is the signal thrown 2207 * when the application is issuing a syscall which is not allowed. The 2208 * main purpose of this function is to help with debugging by identifying 2209 * filtered syscalls. 2210 */ 2211 static int 2212 install_sigsys_debugging(void) 2213 { 2214 struct sigaction act; 2215 sigset_t mask; 2216 2217 memset(&act, 0, sizeof(act)); 2218 sigemptyset(&mask); 2219 sigaddset(&mask, SIGSYS); 2220 2221 act.sa_sigaction = &sigsys_debugging; 2222 act.sa_flags = SA_SIGINFO; 2223 if (sigaction(SIGSYS, &act, NULL) < 0) { 2224 log_err(LD_BUG,"(Sandbox) Failed to register SIGSYS signal handler"); 2225 return -1; 2226 } 2227 2228 if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) { 2229 log_err(LD_BUG,"(Sandbox) Failed call to sigprocmask()"); 2230 return -2; 2231 } 2232 2233 return 0; 2234 } 2235 2236 /** 2237 * Function responsible of registering the sandbox_cfg_t list of parameter 2238 * syscall filters to the existing parameter list. This is used for incipient 2239 * multiple-sandbox support. 2240 */ 2241 static int 2242 register_cfg(sandbox_cfg_t* cfg) 2243 { 2244 sandbox_cfg_t *elem = NULL; 2245 2246 if (filter_dynamic == NULL) { 2247 filter_dynamic = cfg; 2248 return 0; 2249 } 2250 2251 for (elem = filter_dynamic; elem->next != NULL; elem = elem->next) 2252 ; 2253 2254 elem->next = cfg; 2255 2256 return 0; 2257 } 2258 2259 #endif /* defined(USE_LIBSECCOMP) */ 2260 2261 #ifdef USE_LIBSECCOMP 2262 /** 2263 * Initialises the syscall sandbox filter for any linux architecture, taking 2264 * into account various available features for different linux flavours. 2265 */ 2266 static int 2267 initialise_libseccomp_sandbox(sandbox_cfg_t* cfg) 2268 { 2269 /* Prevent glibc from trying to open /dev/tty on fatal error */ 2270 setenv("LIBC_FATAL_STDERR_", "1", 1); 2271 2272 if (install_sigsys_debugging()) 2273 return -1; 2274 2275 if (install_syscall_filter(cfg)) 2276 return -2; 2277 2278 if (register_cfg(cfg)) 2279 return -3; 2280 2281 return 0; 2282 } 2283 2284 int 2285 sandbox_is_active(void) 2286 { 2287 return sandbox_active != 0; 2288 } 2289 #endif /* defined(USE_LIBSECCOMP) */ 2290 2291 sandbox_cfg_t* 2292 sandbox_cfg_new(void) 2293 { 2294 return NULL; 2295 } 2296 2297 int 2298 sandbox_init(sandbox_cfg_t *cfg) 2299 { 2300 #if defined(USE_LIBSECCOMP) 2301 return initialise_libseccomp_sandbox(cfg); 2302 2303 #elif defined(__linux__) 2304 (void)cfg; 2305 log_warn(LD_GENERAL, 2306 "This version of Tor was built without support for sandboxing. To " 2307 "build with support for sandboxing on Linux, you must have " 2308 "libseccomp and its necessary header files (e.g. seccomp.h)."); 2309 return 0; 2310 2311 #else 2312 (void)cfg; 2313 log_warn(LD_GENERAL, 2314 "Currently, sandboxing is only implemented on Linux. The feature " 2315 "is disabled on your platform."); 2316 return 0; 2317 #endif /* defined(USE_LIBSECCOMP) || ... */ 2318 } 2319 2320 #ifndef USE_LIBSECCOMP 2321 int 2322 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file) 2323 { 2324 (void)cfg; (void)file; 2325 return 0; 2326 } 2327 2328 int 2329 sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) 2330 { 2331 (void)cfg; (void)file; 2332 return 0; 2333 } 2334 2335 int 2336 sandbox_cfg_allow_opendir_dirname(sandbox_cfg_t **cfg, char *dir) 2337 { 2338 (void)cfg; (void)dir; 2339 return 0; 2340 } 2341 2342 int 2343 sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) 2344 { 2345 (void)cfg; (void)file; 2346 return 0; 2347 } 2348 2349 int 2350 sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file) 2351 { 2352 (void)cfg; (void)file; 2353 return 0; 2354 } 2355 2356 int 2357 sandbox_cfg_allow_chmod_filename(sandbox_cfg_t **cfg, char *file) 2358 { 2359 (void)cfg; (void)file; 2360 return 0; 2361 } 2362 2363 int 2364 sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) 2365 { 2366 (void)cfg; (void)file1; (void)file2; 2367 return 0; 2368 } 2369 2370 int 2371 sandbox_is_active(void) 2372 { 2373 return 0; 2374 } 2375 2376 #endif /* !defined(USE_LIBSECCOMP) */