diff options
Diffstat (limited to 'src/lib/sandbox')
-rw-r--r-- | src/lib/sandbox/sandbox.c | 146 | ||||
-rw-r--r-- | src/lib/sandbox/sandbox.h | 2 |
2 files changed, 138 insertions, 10 deletions
diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index 7a57554ace..6800fa062b 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -58,6 +58,10 @@ #include <linux/futex.h> #include <sys/file.h> +#ifdef ENABLE_FRAGILE_HARDENING +#include <sys/ptrace.h> +#endif + #include <stdarg.h> #include <seccomp.h> #include <signal.h> @@ -148,7 +152,11 @@ static sandbox_cfg_t *filter_dynamic = NULL; static int filter_nopar_gen[] = { SCMP_SYS(access), SCMP_SYS(brk), +#ifdef __NR_clock_gettime64 + SCMP_SYS(clock_gettime64), +#else SCMP_SYS(clock_gettime), +#endif SCMP_SYS(close), SCMP_SYS(clone), SCMP_SYS(dup), @@ -194,6 +202,9 @@ static int filter_nopar_gen[] = { SCMP_SYS(getgid32), #endif SCMP_SYS(getpid), +#ifdef ENABLE_FRAGILE_HARDENING + SCMP_SYS(getppid), +#endif #ifdef __NR_getrlimit SCMP_SYS(getrlimit), #endif @@ -247,6 +258,9 @@ static int filter_nopar_gen[] = { SCMP_SYS(sigreturn), #endif SCMP_SYS(stat), +#if defined(__i386__) && defined(__NR_statx) + SCMP_SYS(statx), +#endif SCMP_SYS(uname), SCMP_SYS(wait4), SCMP_SYS(write), @@ -345,6 +359,7 @@ sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return rc; } +#ifdef __NR_time /** * Function responsible for setting up the time syscall for * the seccomp filter sandbox. @@ -353,13 +368,11 @@ static int sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { (void) filter; -#ifdef __NR_time + return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time), SCMP_CMP(0, SCMP_CMP_EQ, 0)); -#else - return 0; -#endif /* defined(__NR_time) */ } +#endif /* defined(__NR_time) */ /** * Function responsible for setting up the accept4 syscall for @@ -538,6 +551,24 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) int use_openat = libc_uses_openat_for_open(); +#ifdef ENABLE_FRAGILE_HARDENING + /* AddressSanitizer uses the "open" syscall to access information about the + * running process via the filesystem, so that call must be allowed without + * restriction or the sanitizer will be unable to execute normally when the + * process terminates. */ + rc = seccomp_rule_add_0(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " + "libseccomp error %d", rc); + return rc; + } + + /* If glibc also uses only the "open" syscall to open files on this system + * there is no need to consider any additional rules. */ + if (!use_openat) + return 0; +#endif + // for each dynamic parameter filters for (elem = filter; elem != NULL; elem = elem->next) { smp_param_t *param = elem->param; @@ -581,6 +612,32 @@ sb_chmod(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +#ifdef __i386__ +static int +sb_chown32(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +{ + int rc; + sandbox_cfg_t *elem = NULL; + + // for each dynamic parameter filters + for (elem = filter; elem != NULL; elem = elem->next) { + smp_param_t *param = elem->param; + + if (param != NULL && param->prot == 1 && param->syscall + == SCMP_SYS(chown32)) { + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chown32), + SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); + if (rc != 0) { + log_err(LD_BUG,"(Sandbox) failed to add chown32 syscall, received " + "libseccomp error %d", rc); + return rc; + } + } + } + + return 0; +} +#else static int sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { @@ -605,6 +662,7 @@ sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +#endif /* defined(__i386__) */ /** * Function responsible for setting up the rename syscall for @@ -693,6 +751,34 @@ sb_opendir(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +#ifdef ENABLE_FRAGILE_HARDENING +/** + * Function responsible for setting up the ptrace syscall for + * the seccomp filter sandbox. + */ +static int +sb_ptrace(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +{ + int rc; + pid_t pid = getpid(); + (void) filter; + + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace), + SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_ATTACH), + SCMP_CMP(1, SCMP_CMP_EQ, pid)); + if (rc) + return rc; + + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ptrace), + SCMP_CMP(0, SCMP_CMP_EQ, PTRACE_GETREGS), + SCMP_CMP(1, SCMP_CMP_EQ, pid)); + if (rc) + return rc; + + return 0; +} +#endif + /** * Function responsible for setting up the socket syscall for * the seccomp filter sandbox. @@ -740,7 +826,7 @@ sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP)); if (rc) return rc; -#endif +#endif /* defined(ENABLE_NSS) */ rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX), @@ -868,6 +954,14 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return rc; #endif /* defined(IPV6_V6ONLY) */ +#ifdef IP_BIND_ADDRESS_NO_PORT + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), + SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), + SCMP_CMP(2, SCMP_CMP_EQ, IP_BIND_ADDRESS_NO_PORT)); + if (rc) + return rc; +#endif + return 0; } @@ -1015,6 +1109,18 @@ sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) int rc = 0; (void) filter; +#ifdef ENABLE_FRAGILE_HARDENING + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), + SCMP_CMP(0, SCMP_CMP_EQ, PR_GET_DUMPABLE)); + if (rc) + return rc; + + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), + SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_PTRACER)); + if (rc) + return rc; +#endif + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE)); if (rc) @@ -1059,6 +1165,13 @@ sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter) int rc = 0; (void) filter; +#ifdef ENABLE_FRAGILE_HARDENING + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), + SCMP_CMP(0, SCMP_CMP_EQ, SIG_BLOCK)); + if (rc) + return rc; +#endif + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK)); if (rc) @@ -1198,16 +1311,25 @@ sb_kill(scmp_filter_ctx ctx, sandbox_cfg_t *filter) static sandbox_filter_func_t filter_func[] = { sb_rt_sigaction, sb_rt_sigprocmask, +#ifdef __NR_time sb_time, +#endif sb_accept4, #ifdef __NR_mmap2 sb_mmap2, #endif +#ifdef __i386__ + sb_chown32, +#else sb_chown, +#endif sb_chmod, sb_open, sb_openat, sb_opendir, +#ifdef ENABLE_FRAGILE_HARDENING + sb_ptrace, +#endif sb_rename, #ifdef __NR_fcntl64 sb_fcntl64, @@ -1474,6 +1596,12 @@ new_element(int syscall, char *value) return new_element2(syscall, value, NULL); } +#ifdef __i386__ +#define SCMP_chown SCMP_SYS(chown32) +#else +#define SCMP_chown SCMP_SYS(chown) +#endif + #ifdef __NR_stat64 #define SCMP_stat SCMP_SYS(stat64) #else @@ -1524,7 +1652,7 @@ sandbox_cfg_allow_chown_filename(sandbox_cfg_t **cfg, char *file) { sandbox_cfg_t *elem = NULL; - elem = new_element(SCMP_SYS(chown), file); + elem = new_element(SCMP_chown, file); elem->next = *cfg; *cfg = elem; @@ -1719,7 +1847,7 @@ get_syscall_from_ucontext(const ucontext_t *ctx) { return (int) ctx->uc_mcontext.M_SYSCALL; } -#else +#else /* !defined(SYSCALL_NAME_DEBUGGING) */ static const char * get_syscall_name(int syscall_num) { @@ -1732,7 +1860,7 @@ get_syscall_from_ucontext(const ucontext_t *ctx) (void) ctx; return -1; } -#endif +#endif /* defined(SYSCALL_NAME_DEBUGGING) */ #ifdef USE_BACKTRACE #define MAX_DEPTH 256 diff --git a/src/lib/sandbox/sandbox.h b/src/lib/sandbox/sandbox.h index eba99afbde..17d32d16de 100644 --- a/src/lib/sandbox/sandbox.h +++ b/src/lib/sandbox/sandbox.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** |