#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../logger.h" #include "../utils.h" #include "../random.h" #include "sandbox-linux.h" /* TODO: make a whitelist approach. So far we simply blacklist * obvious systemcalls. To whitelist, we need to analyse our * dependencies (http library, sqlite wrapper, sqlite lib etc.) */ bool SandboxLinux::supported() { std::fstream stream; stream.open("/proc/sys/kernel/unprivileged_userns_clone"); if(stream.is_open()) { std::string str; stream >> str; if(str[0] == '0') { Logger::error() << "Please write '1' to /proc/sys/kernel/unprivileged_userns_clone in order to enable " "sandboxing support on this system"; return false; } } return true; } bool SandboxLinux::enable(std::vector fsPaths) { std::sort(fsPaths.begin(), fsPaths.end(), [](const std::string &a, const std::string &b) { return a.length() < b.length(); }); struct qssb_policy *policy = qssb_init_policy(); if(policy == NULL) { Logger::error() << "Failed to init sandboxing policy (worker) "; return false; } for(unsigned int i = 0; i < fsPaths.size(); i++) { qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_WRITE, fsPaths[i].c_str()); } policy->drop_caps = 1; policy->not_dumpable = 1; policy->no_new_privs = 1; policy->mount_path_policies_to_chroot = 1; /* TODO: as said, a whitelist approach is better. As such, this list is bound to be incomplete in the * sense that more could be listed here and some critical ones are probably missing */ /* TODO: use qssb groups */ long blacklisted_syscalls[] = {QSSB_SYS(setuid), QSSB_SYS(connect), QSSB_SYS(chroot), QSSB_SYS(pivot_root), QSSB_SYS(mount), QSSB_SYS(setns), QSSB_SYS(unshare), QSSB_SYS(ptrace), QSSB_SYS(personality), QSSB_SYS(prctl), QSSB_SYS(execveat), QSSB_SYS(execve), QSSB_SYS(fork)}; qssb_append_syscalls_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, blacklisted_syscalls, sizeof(blacklisted_syscalls) / sizeof(blacklisted_syscalls[0])); qssb_append_syscall_default_policy(policy, QSSB_SYSCALL_ALLOW); if(qssb_enable_policy(policy) != 0) { Logger::error() << "Sandbox: Activation of seccomp blacklist failed!"; qssb_free_policy(policy); return false; } qssb_free_policy(policy); return true; }