Allow optional localhost network access to sandboxed derivations

This will allow bind and connect to 127.0.0.1, which can reduce purity/
security (if you're running a vulnerable service on localhost) but is
also needed for a ton of test suites, so I'm leaving it turned off by
default but allowing certain derivations to turn it on as needed.

It also allows DNS resolution of arbitrary hostnames but I haven't found
a way to avoid that. In principle I'd just want to allow resolving
localhost but that doesn't seem to be possible.

I don't think this belongs under `build-use-sandbox = relaxed` because we
want it on Hydra and I don't think it's the end of the world.
This commit is contained in:
Dan Peebles 2017-10-30 17:25:41 +01:00
parent 6e5165b773
commit 4a4a009f78
2 changed files with 33 additions and 5 deletions

View file

@ -2774,10 +2774,10 @@ void DerivationGoal::runChild()
sandboxProfile += "(deny default (with no-log))\n"; sandboxProfile += "(deny default (with no-log))\n";
} }
sandboxProfile += "(import \"sandbox-defaults.sb\")"; sandboxProfile += "(import \"sandbox-defaults.sb\")\n";
if (fixedOutput) if (fixedOutput)
sandboxProfile += "(import \"sandbox-network.sb\")"; sandboxProfile += "(import \"sandbox-network.sb\")\n";
/* Our rwx outputs */ /* Our rwx outputs */
sandboxProfile += "(allow file-read* file-write* process-exec\n"; sandboxProfile += "(allow file-read* file-write* process-exec\n";
@ -2820,7 +2820,7 @@ void DerivationGoal::runChild()
sandboxProfile += additionalSandboxProfile; sandboxProfile += additionalSandboxProfile;
} else } else
sandboxProfile += "(import \"sandbox-minimal.sb\")"; sandboxProfile += "(import \"sandbox-minimal.sb\")\n";
debug("Generated sandbox profile:"); debug("Generated sandbox profile:");
debug(sandboxProfile); debug(sandboxProfile);
@ -2829,6 +2829,8 @@ void DerivationGoal::runChild()
writeFile(sandboxFile, sandboxProfile); writeFile(sandboxFile, sandboxProfile);
bool allowLocalNetworking = get(drv->env, "__darwinAllowLocalNetworking") == "1";
/* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms /* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms
to find temporary directories, so we want to open up a broader place for them to dump their files, if needed. */ to find temporary directories, so we want to open up a broader place for them to dump their files, if needed. */
Path globalTmpDir = canonPath(getEnv("TMPDIR", "/tmp"), true); Path globalTmpDir = canonPath(getEnv("TMPDIR", "/tmp"), true);
@ -2844,6 +2846,10 @@ void DerivationGoal::runChild()
args.push_back("_GLOBAL_TMP_DIR=" + globalTmpDir); args.push_back("_GLOBAL_TMP_DIR=" + globalTmpDir);
args.push_back("-D"); args.push_back("-D");
args.push_back("IMPORT_DIR=" + settings.nixDataDir + "/nix/sandbox/"); args.push_back("IMPORT_DIR=" + settings.nixDataDir + "/nix/sandbox/");
if (allowLocalNetworking) {
args.push_back("-D");
args.push_back(string("_ALLOW_LOCAL_NETWORKING=1"));
}
args.push_back(drv->builder); args.push_back(drv->builder);
} }
#endif #endif

View file

@ -30,6 +30,29 @@
; Without this line clang cannot write to /dev/null, breaking some configure tests. ; Without this line clang cannot write to /dev/null, breaking some configure tests.
(allow file-read-metadata (literal "/dev")) (allow file-read-metadata (literal "/dev"))
; Many packages like to do local networking in their test suites, but let's only
; allow it if the package explicitly asks for it.
(if (param "_ALLOW_LOCAL_NETWORKING")
(begin
(allow network* (local ip) (local tcp) (local udp))
; Allow access to /etc/resolv.conf (which is a symlink to
; /private/var/run/resolv.conf).
; TODO: deduplicate with sandbox-network.sb
(allow file-read-metadata
(literal "/var")
(literal "/etc")
(literal "/etc/resolv.conf")
(literal "/private/etc/resolv.conf"))
(allow file-read*
(literal "/private/var/run/resolv.conf"))
; Allow DNS lookups. This is even needed for localhost, which lots of tests rely on
(allow file-read-metadata (literal "/etc/hosts"))
(allow file-read* (literal "/private/etc/hosts"))
(allow network-outbound (remote unix-socket (path-literal "/private/var/run/mDNSResponder")))))
; Standard devices. ; Standard devices.
(allow file* (allow file*
(literal "/dev/null") (literal "/dev/null")
@ -54,5 +77,4 @@
(allow file-read-metadata (allow file-read-metadata
(literal "/etc") (literal "/etc")
(literal "/var") (literal "/var")
(literal "/private/var/tmp") (literal "/private/var/tmp"))
)