aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-04-17 08:04:41 -0400
committerGitHub <noreply@github.com>2023-04-17 08:04:41 -0400
commit72ffa7fedb34585948f8c9a47bfaebeb6cc5d537 (patch)
treeb0feb3dbeb6c347371e78ce025212e704588f276 /src/libstore
parent9af9c260fc0aff9e20a1c2e965249a20394ca22a (diff)
parentddebeb934a20225eec518520c96768bf00f0810a (diff)
Merge pull request #7732 from hercules-ci/make-initLibStore-viable-alternative
Make `initLibStore` a viable alternative
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/globals.cc63
-rw-r--r--src/libstore/globals.hh5
2 files changed, 62 insertions, 6 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 823b4af74..1b38e32fb 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -7,12 +7,20 @@
#include <algorithm>
#include <map>
+#include <mutex>
#include <thread>
#include <dlfcn.h>
#include <sys/utsname.h>
#include <nlohmann/json.hpp>
+#include <sodium/core.h>
+
+#ifdef __GLIBC__
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <dlfcn.h>
+#endif
namespace nix {
@@ -41,7 +49,6 @@ Settings::Settings()
, nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
{
buildUsersGroup = getuid() == 0 ? "nixbld" : "";
- lockCPU = getEnv("NIX_AFFINITY_HACK") == "1";
allowSymlinkedStore = getEnv("NIX_IGNORE_SYMLINK_STORE") == "1";
auto sslOverride = getEnv("NIX_SSL_CERT_FILE").value_or(getEnv("SSL_CERT_FILE").value_or(""));
@@ -281,6 +288,42 @@ void initPlugins()
settings.pluginFiles.pluginsLoaded = true;
}
+static void preloadNSS()
+{
+ /* builtin:fetchurl can trigger a DNS lookup, which with glibc can trigger a dynamic library load of
+ one of the glibc NSS libraries in a sandboxed child, which will fail unless the library's already
+ been loaded in the parent. So we force a lookup of an invalid domain to force the NSS machinery to
+ load its lookup libraries in the parent before any child gets a chance to. */
+ static std::once_flag dns_resolve_flag;
+
+ std::call_once(dns_resolve_flag, []() {
+#ifdef __GLIBC__
+ /* On linux, glibc will run every lookup through the nss layer.
+ * That means every lookup goes, by default, through nscd, which acts as a local
+ * cache.
+ * Because we run builds in a sandbox, we also remove access to nscd otherwise
+ * lookups would leak into the sandbox.
+ *
+ * But now we have a new problem, we need to make sure the nss_dns backend that
+ * does the dns lookups when nscd is not available is loaded or available.
+ *
+ * We can't make it available without leaking nix's environment, so instead we'll
+ * load the backend, and configure nss so it does not try to run dns lookups
+ * through nscd.
+ *
+ * This is technically only used for builtins:fetch* functions so we only care
+ * about dns.
+ *
+ * All other platforms are unaffected.
+ */
+ if (!dlopen(LIBNSS_DNS_SO, RTLD_NOW))
+ warn("unable to load nss_dns backend");
+ // FIXME: get hosts entry from nsswitch.conf.
+ __nss_configure_lookup("hosts", "files dns");
+#endif
+ });
+}
+
static bool initLibStoreDone = false;
void assertLibStoreInitialized() {
@@ -291,6 +334,24 @@ void assertLibStoreInitialized() {
}
void initLibStore() {
+
+ initLibUtil();
+
+ if (sodium_init() == -1)
+ throw Error("could not initialise libsodium");
+
+ loadConfFile();
+
+ preloadNSS();
+
+ /* On macOS, don't use the per-session TMPDIR (as set e.g. by
+ sshd). This breaks build users because they don't have access
+ to the TMPDIR, in particular in ‘nix-store --serve’. */
+#if __APPLE__
+ if (hasPrefix(getEnv("TMPDIR").value_or("/tmp"), "/var/folders/"))
+ unsetenv("TMPDIR");
+#endif
+
initLibStoreDone = true;
}
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index f598ed4a8..d6c5d437a 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -458,11 +458,6 @@ public:
)",
{"env-keep-derivations"}};
- /**
- * Whether to lock the Nix client and worker to the same CPU.
- */
- bool lockCPU;
-
Setting<SandboxMode> sandboxMode{
this,
#if __linux__