Run all derivation builders inside the sandbox on macOS
This replaces the external sandbox-exec call with direct calls into libsandbox. This API is technically deprecated and is missing some prototypes, but all major browsers depend on it, so it is unlikely to materially change without warning. This commit also ensures the netrc file is only written if the derivation is in fact meant to be able to access the internet. This change commits a sin of not actually actively declaring its dependency on macOS's libsandbox.dylib; this is due to the dylib cache in macOS making that explicit dependency unnecessary. In the future this might become a problem, so this commit marks our sins. Co-authored-by: Artemis Tosini <lix@artem.ist> Co-authored-by: Lunaphied <lunaphied@lunaphied.me> Change-Id: Ia302141a53ce7b0327c1aad86a117b6645fe1189
This commit is contained in:
parent
76b45b4861
commit
0c831765bd
1 changed files with 115 additions and 121 deletions
|
@ -52,6 +52,9 @@
|
|||
#if __APPLE__
|
||||
#include <spawn.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
/* This definition is undocumented but depended upon by all major browsers. */
|
||||
extern "C" int sandbox_init_with_parameters(const char *profile, uint64_t flags, const char *const parameters[], char **errorbuf);
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
|
@ -1711,7 +1714,7 @@ void LocalDerivationGoal::runChild()
|
|||
(which may run under a different uid and/or in a sandbox). */
|
||||
std::string netrcData;
|
||||
try {
|
||||
if (drv->isBuiltin() && drv->builder == "builtin:fetchurl")
|
||||
if (drv->isBuiltin() && drv->builder == "builtin:fetchurl" && !derivationType->isSandboxed())
|
||||
netrcData = readFile(settings.netrcFile);
|
||||
} catch (SysError &) { }
|
||||
|
||||
|
@ -2005,11 +2008,7 @@ void LocalDerivationGoal::runChild()
|
|||
|
||||
std::string builder = "invalid";
|
||||
|
||||
if (drv->isBuiltin()) {
|
||||
;
|
||||
}
|
||||
#if __APPLE__
|
||||
else {
|
||||
/* This has to appear before import statements. */
|
||||
std::string sandboxProfile = "(version 1)\n";
|
||||
|
||||
|
@ -2078,13 +2077,13 @@ void LocalDerivationGoal::runChild()
|
|||
i.first, i.second.source);
|
||||
|
||||
std::string path = i.first;
|
||||
auto optSt = maybeLstat(path.c_str());
|
||||
if (!optSt) {
|
||||
if (i.second.optional)
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st)) {
|
||||
if (i.second.optional && errno == ENOENT)
|
||||
continue;
|
||||
throw SysError("getting attributes of required path '%s", path);
|
||||
throw SysError("getting attributes of path '%s", path);
|
||||
}
|
||||
if (S_ISDIR(optSt->st_mode))
|
||||
if (S_ISDIR(st.st_mode))
|
||||
sandboxProfile += fmt("\t(subpath \"%s\")\n", path);
|
||||
else
|
||||
sandboxProfile += fmt("\t(literal \"%s\")\n", path);
|
||||
|
@ -2107,10 +2106,6 @@ void LocalDerivationGoal::runChild()
|
|||
debug("Generated sandbox profile:");
|
||||
debug(sandboxProfile);
|
||||
|
||||
Path sandboxFile = tmpDir + "/.sandbox.sb";
|
||||
|
||||
writeFile(sandboxFile, sandboxProfile);
|
||||
|
||||
bool allowLocalNetworking = parsedDrv->getBoolAttr("__darwinAllowLocalNetworking");
|
||||
|
||||
/* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms
|
||||
|
@ -2121,24 +2116,23 @@ void LocalDerivationGoal::runChild()
|
|||
if (globalTmpDir.back() == '/') globalTmpDir.pop_back();
|
||||
|
||||
if (getEnv("_NIX_TEST_NO_SANDBOX") != "1") {
|
||||
builder = "/usr/bin/sandbox-exec";
|
||||
args.push_back("sandbox-exec");
|
||||
args.push_back("-f");
|
||||
args.push_back(sandboxFile);
|
||||
args.push_back("-D");
|
||||
args.push_back("_GLOBAL_TMP_DIR=" + globalTmpDir);
|
||||
Strings sandboxArgs;
|
||||
sandboxArgs.push_back("_GLOBAL_TMP_DIR");
|
||||
sandboxArgs.push_back(globalTmpDir);
|
||||
if (allowLocalNetworking) {
|
||||
args.push_back("-D");
|
||||
args.push_back(std::string("_ALLOW_LOCAL_NETWORKING=1"));
|
||||
sandboxArgs.push_back("_ALLOW_LOCAL_NETWORKING");
|
||||
sandboxArgs.push_back("1");
|
||||
}
|
||||
args.push_back(drv->builder);
|
||||
} else {
|
||||
if (sandbox_init_with_parameters(sandboxProfile.c_str(), 0, stringsToCharPtrs(sandboxArgs).data(), NULL)) {
|
||||
writeFull(STDERR_FILENO, "failed to configure sandbox\n");
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
builder = drv->builder;
|
||||
args.push_back(std::string(baseNameOf(drv->builder)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
else {
|
||||
if (!drv->isBuiltin()) {
|
||||
builder = drv->builder;
|
||||
args.push_back(std::string(baseNameOf(drv->builder)));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue