Merge pull request #6814 from amjoseph-nixpkgs/pr/sandbox-error-messages
local-derivation-goal.cc: improve error messages when sandboxing fails
This commit is contained in:
commit
2805439335
|
@ -845,18 +845,43 @@ void LocalDerivationGoal::startBuilder()
|
||||||
/* Some distros patch Linux to not allow unprivileged
|
/* Some distros patch Linux to not allow unprivileged
|
||||||
* user namespaces. If we get EPERM or EINVAL, try
|
* user namespaces. If we get EPERM or EINVAL, try
|
||||||
* without CLONE_NEWUSER and see if that works.
|
* without CLONE_NEWUSER and see if that works.
|
||||||
|
* Details: https://salsa.debian.org/kernel-team/linux/-/commit/d98e00eda6bea437e39b9e80444eee84a32438a6
|
||||||
*/
|
*/
|
||||||
usingUserNamespace = false;
|
usingUserNamespace = false;
|
||||||
flags &= ~CLONE_NEWUSER;
|
flags &= ~CLONE_NEWUSER;
|
||||||
child = clone(childEntry, stack + stackSize, flags, this);
|
child = clone(childEntry, stack + stackSize, flags, this);
|
||||||
}
|
}
|
||||||
/* Otherwise exit with EPERM so we can handle this in the
|
if (child == -1) {
|
||||||
parent. This is only done when sandbox-fallback is set
|
switch(errno) {
|
||||||
to true (the default). */
|
case EPERM:
|
||||||
if (child == -1 && (errno == EPERM || errno == EINVAL) && settings.sandboxFallback)
|
case EINVAL: {
|
||||||
_exit(1);
|
int errno_ = errno;
|
||||||
if (child == -1) throw SysError("cloning builder process");
|
if (!userNamespacesEnabled && errno==EPERM)
|
||||||
|
notice("user namespaces appear to be disabled; they are required for sandboxing; check /proc/sys/user/max_user_namespaces");
|
||||||
|
if (userNamespacesEnabled) {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Path procSelfNsUser = "/proc/self/ns/user";
|
||||||
|
if (!pathExists(procSelfNsUser))
|
||||||
|
notice("/proc/self/ns/user does not exist; your kernel was likely built without CONFIG_USER_NS=y, which is required for sandboxing");
|
||||||
|
/* Otherwise exit with EPERM so we can handle this in the
|
||||||
|
parent. This is only done when sandbox-fallback is set
|
||||||
|
to true (the default). */
|
||||||
|
if (settings.sandboxFallback)
|
||||||
|
_exit(1);
|
||||||
|
/* Mention sandbox-fallback in the error message so the user
|
||||||
|
knows that having it disabled contributed to the
|
||||||
|
unrecoverability of this failure */
|
||||||
|
throw SysError(errno_, "creating sandboxed builder process using clone(), without sandbox-fallback");
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw SysError("creating sandboxed builder process using clone()");
|
||||||
|
}
|
||||||
|
}
|
||||||
writeFull(builderOut.writeSide.get(),
|
writeFull(builderOut.writeSide.get(),
|
||||||
fmt("%d %d\n", usingUserNamespace, child));
|
fmt("%d %d\n", usingUserNamespace, child));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
|
|
@ -204,13 +204,19 @@ public:
|
||||||
int errNo;
|
int errNo;
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
SysError(const Args & ... args)
|
SysError(int errNo_, const Args & ... args)
|
||||||
: Error("")
|
: Error("")
|
||||||
{
|
{
|
||||||
errNo = errno;
|
errNo = errNo_;
|
||||||
auto hf = hintfmt(args...);
|
auto hf = hintfmt(args...);
|
||||||
err.msg = hintfmt("%1%: %2%", normaltxt(hf.str()), strerror(errNo));
|
err.msg = hintfmt("%1%: %2%", normaltxt(hf.str()), strerror(errNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
SysError(const Args & ... args)
|
||||||
|
: SysError(errno, args ...)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue