Create escape hatch for supplementary group sandboxing woes

There is no obvious good solution for this that has occured to anyone.
This commit is contained in:
John Ericson 2023-05-08 14:41:47 -04:00
parent 4539ab530a
commit 6d1aa523de
2 changed files with 23 additions and 9 deletions

View file

@ -907,14 +907,9 @@ void LocalDerivationGoal::startBuilder()
openSlave(); openSlave();
/* Drop additional groups here because we can't do it /* Drop additional groups here because we can't do it
after we've created the new user namespace. FIXME: after we've created the new user namespace. */
this means that if we're not root in the parent if (settings.dropSupplementaryGroups)
namespace, we can't drop additional groups; they will if (setgroups(0, 0) == -1)
be mapped to nogroup in the child namespace. There does
not seem to be a workaround for this. (But who can tell
from reading user_namespaces(7)?)
See also https://lwn.net/Articles/621612/. */
if (getuid() == 0 && setgroups(0, 0) == -1)
throw SysError("setgroups failed"); throw SysError("setgroups failed");
ProcessOptions options; ProcessOptions options;

View file

@ -515,6 +515,25 @@ public:
Setting<bool> sandboxFallback{this, true, "sandbox-fallback", Setting<bool> sandboxFallback{this, true, "sandbox-fallback",
"Whether to disable sandboxing when the kernel doesn't allow it."}; "Whether to disable sandboxing when the kernel doesn't allow it."};
Setting<bool> dropSupplementaryGroups{this, getuid() == 0, "drop-supplementary-groups",
R"(
Whether to drop supplementary groups when building with sandboxing.
This is normally a good idea if we are root and have the capability to
do so.
But if this "root" is mapped from a non-root user in a larger
namespace, we won't be able drop additional groups; they will be
mapped to nogroup in the child namespace. There does not seem to be a
workaround for this.
(But who can tell from reading user_namespaces(7)? See also https://lwn.net/Articles/621612/.)
TODO: It might be good to create a middle ground option that allows
`setgroups` to fail if all additional groups are "nogroup" / the value
of `/proc/sys/fs/overflowuid`. This would handle the common
nested-sandboxing case identified above.
)"};
#if __linux__ #if __linux__
Setting<std::string> sandboxShmSize{ Setting<std::string> sandboxShmSize{
this, "50%", "sandbox-dev-shm-size", this, "50%", "sandbox-dev-shm-size",