From 0cd353a7b71db740ac02635aa09c20f531b8a53e Mon Sep 17 00:00:00 2001 From: netblue30 Date: Thu, 15 Oct 2015 12:26:49 -0400 Subject: new syscalls added to default seccomp filter --- todo | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'todo') diff --git a/todo b/todo index b2c98014c..e8fa68928 100644 --- a/todo +++ b/todo @@ -45,3 +45,137 @@ make[1]: *** [seccomp.o] Error 1 7. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI) RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog, + +8. To investigate +void SupervisorMain::setupSeccomp() { + // Install a rudimentary seccomp blacklist. + // TODO(security): Change this to a whitelist. + + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == nullptr) + KJ_FAIL_SYSCALL("seccomp_init", 0); // No real error code + KJ_DEFER(seccomp_release(ctx)); + +#define CHECK_SECCOMP(call) \ + do { \ + if (auto result = (call)) { \ + KJ_FAIL_SYSCALL(#call, -result); \ + } \ + } while (0) + + // Native code only for now, so there are no seccomp_arch_add calls. + + // Redundant, but this is standard and harmless. + CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 1)); + + // It's easy to inadvertently issue an x32 syscall (e.g. syscall(-1)). Such syscalls + // should fail, but there's no need to kill the issuer. + CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ERRNO(ENOSYS))); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" // SCMP_* macros produce these + // Disable some things that seem scary. + if (!devmode) { + // ptrace is scary + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 0)); + } else { + // Try to be somewhat safe with ptrace in dev mode. Note that the ability to modify + // orig_ax using ptrace allows a complete seccomp bypass. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_POKEUSER))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGS))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETFPREGS))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGSET))); + } + + // Restrict the set of allowable network protocol families + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_GE, AF_NETLINK + 1))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_AX25))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_IPX))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_APPLETALK))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_NETROM))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_BRIDGE))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_ATMPVC))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_X25))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_ROSE))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_DECnet))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_NETBEUI))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_SECURITY))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_KEY))); +#pragma GCC diagnostic pop + + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(add_key), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(request_key), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(keyctl), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(syslog), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(uselib), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(personality), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(acct), 0)); + + // 16-bit code is unnecessary in the sandbox, and modify_ldt is a historic source + // of interesting information leaks. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(modify_ldt), 0)); + + // Despite existing at a 64-bit syscall, set_thread_area is only useful + // for 32-bit programs. 64-bit programs use arch_prctl instead. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_thread_area), 0)); + + // Disable namespaces. Nested sandboxing could be useful but the attack surface is large. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(unshare), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mount), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(pivot_root), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(quotactl), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1, + SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER))); + + // AIO is scary. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_setup), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_destroy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_getevents), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_submit), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_cancel), 0)); + + // Scary vm syscalls + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(remap_file_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mbind), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_mempolicy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_mempolicy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(migrate_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(move_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(vmsplice), 0)); + + // Scary futex operations + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_robust_list), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_robust_list), 0)); + + // Utterly terrifying profiling operations + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(perf_event_open), 0)); + + // TOOD(someday): See if we can get away with turning off mincore, madvise, sysinfo etc. + + // TODO(someday): Turn off POSIX message queues and other such esoteric features. + + if (seccompDumpPfc) { + seccomp_export_pfc(ctx, 1); + } + + CHECK_SECCOMP(seccomp_load(ctx)); + +#undef CHECK_SECCOMP +} -- cgit v1.2.3-54-g00ecf