qswiki/sandbox/sandbox-linux.cpp

91 lines
2.5 KiB
C++

#include <vector>
#include <initializer_list>
#include <string.h>
#include <sched.h>
#include <unistd.h>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <filesystem>
#include <sys/mount.h>
#include <sys/capability.h>
#define HAVE_LANDLOCK 0
#include <exile.h>
#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<std::string> fsPaths)
{
std::sort(fsPaths.begin(), fsPaths.end(),
[](const std::string &a, const std::string &b) { return a.length() < b.length(); });
struct exile_policy *policy = exile_init_policy();
if(policy == NULL)
{
Logger::error() << "Failed to init sandboxing policy (worker) ";
return false;
}
for(unsigned int i = 0; i < fsPaths.size(); i++)
{
exile_append_path_policy(policy, EXILE_FS_ALLOW_READ | EXILE_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;
if(exile_append_group_syscall_policy(policy, EXILE_SYSCALL_ALLOW, EXILE_SYSCGROUP_DEFAULT_ALLOW) != 0)
{
Logger::error() << "Sandbox: Failed to add whitelist!";
exile_free_policy(policy);
return false;
}
if(exile_append_group_syscall_policy(policy, EXILE_SYSCALL_ALLOW, EXILE_SYSCGROUP_SOCKET | EXILE_SYSCGROUP_FUTEX | EXILE_SYSCGROUP_PATH | EXILE_SYSCGROUP_SCHED | EXILE_SYSCGROUP_TIME) != 0)
{
Logger::error() << "Sandbox: Failed to add socket group!";
exile_free_policy(policy);
return false;
}
if(exile_append_syscall_default_policy(policy, EXILE_SYSCALL_DENY_KILL_PROCESS) != 0)
{
Logger::error() << "Sandbox: Default policy";
exile_free_policy(policy);
return false;
}
if(exile_enable_policy(policy) != 0)
{
Logger::error() << "Sandbox: Activation of seccomp blacklist failed!";
exile_free_policy(policy);
return false;
}
exile_free_policy(policy);
return true;
}