aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/build/local-derivation-goal.cc39
-rw-r--r--src/libutil/error.hh10
2 files changed, 40 insertions, 9 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index d1ec91ed5..79a241ae0 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -845,18 +845,43 @@ void LocalDerivationGoal::startBuilder()
/* Some distros patch Linux to not allow unprivileged
* user namespaces. If we get EPERM or EINVAL, try
* without CLONE_NEWUSER and see if that works.
+ * Details: https://salsa.debian.org/kernel-team/linux/-/commit/d98e00eda6bea437e39b9e80444eee84a32438a6
*/
usingUserNamespace = false;
flags &= ~CLONE_NEWUSER;
child = clone(childEntry, stack + stackSize, flags, this);
}
- /* 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 (child == -1 && (errno == EPERM || errno == EINVAL) && settings.sandboxFallback)
- _exit(1);
- if (child == -1) throw SysError("cloning builder process");
-
+ if (child == -1) {
+ switch(errno) {
+ case EPERM:
+ case EINVAL: {
+ int errno_ = errno;
+ 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(),
fmt("%d %d\n", usingUserNamespace, child));
_exit(0);
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index a53e9802e..3d1479c54 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -204,13 +204,19 @@ public:
int errNo;
template<typename... Args>
- SysError(const Args & ... args)
+ SysError(int errNo_, const Args & ... args)
: Error("")
{
- errNo = errno;
+ errNo = errNo_;
auto hf = hintfmt(args...);
err.msg = hintfmt("%1%: %2%", normaltxt(hf.str()), strerror(errNo));
}
+
+ template<typename... Args>
+ SysError(const Args & ... args)
+ : SysError(errno, args ...)
+ {
+ }
};
}