forked from lix-project/lix
64 lines
1.7 KiB
C++
64 lines
1.7 KiB
C++
|
#include "namespaces.hh"
|
||
|
#include "util.hh"
|
||
|
|
||
|
#if __linux__
|
||
|
|
||
|
namespace nix {
|
||
|
|
||
|
bool userNamespacesSupported()
|
||
|
{
|
||
|
static bool res = [&]() -> bool
|
||
|
{
|
||
|
if (!pathExists("/proc/self/ns/user")) {
|
||
|
notice("'/proc/self/ns/user' does not exist; your kernel was likely built without CONFIG_USER_NS=y, which is required for sandboxing");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Path maxUserNamespaces = "/proc/sys/user/max_user_namespaces";
|
||
|
if (!pathExists(maxUserNamespaces) ||
|
||
|
trim(readFile(maxUserNamespaces)) == "0")
|
||
|
{
|
||
|
notice("user namespaces appear to be disabled; they are required for sandboxing; check '/proc/sys/user/max_user_namespaces'");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Path procSysKernelUnprivilegedUsernsClone = "/proc/sys/kernel/unprivileged_userns_clone";
|
||
|
if (pathExists(procSysKernelUnprivilegedUsernsClone)
|
||
|
&& trim(readFile(procSysKernelUnprivilegedUsernsClone)) == "0")
|
||
|
{
|
||
|
notice("user namespaces appear to be disabled; they are required for sandboxing; check '/proc/sys/kernel/unprivileged_userns_clone'");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Pid pid = startProcess([&]()
|
||
|
{
|
||
|
auto res = unshare(CLONE_NEWUSER);
|
||
|
_exit(res ? 1 : 0);
|
||
|
});
|
||
|
|
||
|
return pid.wait() == 0;
|
||
|
}();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
bool mountNamespacesSupported()
|
||
|
{
|
||
|
static bool res = [&]() -> bool
|
||
|
{
|
||
|
bool useUserNamespace = userNamespacesSupported();
|
||
|
|
||
|
Pid pid = startProcess([&]()
|
||
|
{
|
||
|
auto res = unshare(CLONE_NEWNS | (useUserNamespace ? CLONE_NEWUSER : 0));
|
||
|
_exit(res ? 1 : 0);
|
||
|
});
|
||
|
|
||
|
return pid.wait() == 0;
|
||
|
}();
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|