1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Make Settings::sandboxPaths well-typed

Parsing logic is moved from `DerivationBuilder`, where is doesn't
belong, to `Settings` itself, where it does.
This commit is contained in:
John Ericson 2025-08-20 12:21:42 -04:00
parent 52212635db
commit a712445a7a
3 changed files with 73 additions and 20 deletions

View file

@ -86,13 +86,22 @@ Settings::Settings()
}
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(SANDBOX_SHELL)
sandboxPaths = tokenizeString<StringSet>("/bin/sh=" SANDBOX_SHELL);
sandboxPaths = {{"/bin/sh", {.source = SANDBOX_SHELL}}};
#endif
/* chroot-like behavior from Apple's sandbox */
#ifdef __APPLE__
sandboxPaths = tokenizeString<StringSet>(
"/System/Library/Frameworks /System/Library/PrivateFrameworks /bin/sh /bin/bash /private/tmp /private/var/tmp /usr/lib");
for (PathView p : {
"/System/Library/Frameworks",
"/System/Library/PrivateFrameworks",
"/bin/sh",
"/bin/bash",
"/private/tmp",
"/private/var/tmp",
"/usr/lib",
}) {
sandboxPaths.get().insert_or_assign(std::string{p}, ChrootPath{.source = std::string{p}});
}
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
#endif
}
@ -317,6 +326,42 @@ void BaseSetting<SandboxMode>::convertToArg(Args & args, const std::string & cat
});
}
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ChrootPath, source, optional)
template<>
PathsInChroot BaseSetting<PathsInChroot>::parse(const std::string & str) const
{
PathsInChroot pathsInChroot;
for (auto i : tokenizeString<StringSet>(str)) {
if (i.empty())
continue;
bool optional = false;
if (i[i.size() - 1] == '?') {
optional = true;
i.pop_back();
}
size_t p = i.find('=');
if (p == std::string::npos)
pathsInChroot[i] = {.source = i, .optional = optional};
else
pathsInChroot[i.substr(0, p)] = {.source = i.substr(p + 1), .optional = optional};
}
return pathsInChroot;
}
template<>
std::string BaseSetting<PathsInChroot>::to_string() const
{
std::vector<std::string> accum;
for (auto & [name, cp] : value) {
std::string s = name == cp.source ? name : name + "=" + cp.source;
if (cp.optional)
s += "?";
accum.push_back(std::move(s));
}
return concatStringsSep(" ", accum);
}
unsigned int MaxBuildJobsSetting::parse(const std::string & str) const
{
if (str == "auto")
@ -329,6 +374,14 @@ unsigned int MaxBuildJobsSetting::parse(const std::string & str) const
}
}
template<>
void BaseSetting<PathsInChroot>::appendOrSet(PathsInChroot newValue, bool append)
{
if (!append)
value.clear();
value.insert(std::make_move_iterator(newValue.begin()), std::make_move_iterator(newValue.end()));
}
static void preloadNSS()
{
/* builtin:fetchurl can trigger a DNS lookup, which with glibc can trigger a dynamic library load of

View file

@ -24,6 +24,20 @@ SandboxMode BaseSetting<SandboxMode>::parse(const std::string & str) const;
template<>
std::string BaseSetting<SandboxMode>::to_string() const;
template<>
PathsInChroot BaseSetting<PathsInChroot>::parse(const std::string & str) const;
template<>
std::string BaseSetting<PathsInChroot>::to_string() const;
template<>
struct BaseSetting<PathsInChroot>::trait
{
static constexpr bool appendable = true;
};
template<>
void BaseSetting<PathsInChroot>::appendOrSet(PathsInChroot newValue, bool append);
struct MaxBuildJobsSetting : public BaseSetting<unsigned int>
{
MaxBuildJobsSetting(
@ -698,7 +712,7 @@ public:
)",
{"build-use-chroot", "build-use-sandbox"}};
Setting<PathSet> sandboxPaths{
Setting<PathsInChroot> sandboxPaths{
this,
{},
"sandbox-paths",

View file

@ -857,24 +857,10 @@ void DerivationBuilderImpl::startBuilder()
PathsInChroot DerivationBuilderImpl::getPathsInSandbox()
{
PathsInChroot pathsInChroot;
/* Allow a user-configurable set of directories from the
host file system. */
for (auto i : settings.sandboxPaths.get()) {
if (i.empty())
continue;
bool optional = false;
if (i[i.size() - 1] == '?') {
optional = true;
i.pop_back();
}
size_t p = i.find('=');
if (p == std::string::npos)
pathsInChroot[i] = {.source = i, .optional = optional};
else
pathsInChroot[i.substr(0, p)] = {.source = i.substr(p + 1), .optional = optional};
}
PathsInChroot pathsInChroot = settings.sandboxPaths.get();
if (hasPrefix(store.storeDir, tmpDirInSandbox())) {
throw Error("`sandbox-build-dir` must not contain the storeDir");
}