From 82f84f5e7fb34cc719ed6ea538a3d1ca7516f23d Mon Sep 17 00:00:00 2001 From: Roman Scherer Date: Sat, 7 Mar 2026 13:10:43 +0100 Subject: [PATCH] daemon: Resolve symlinks in /etc/resolv.conf for slirp4netns chroot. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nix/libstore/build.cc (prepareSlirpChrootAction): Use canonPath(i, true) to resolve symlinks when adding /etc/resolv.conf and /etc/hosts to the slirp4netns chroot, so that bindMount receives a regular file path instead of a symlink. On systems using systemd-resolved, /etc/resolv.conf is typically a symlink: /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf The slirp4netns chroot creates an empty /run/ directory, so when bindMount copies the symlink verbatim (spawn.cc line 537-542), the target does not exist and slirp4netns cannot determine the upstream DNS server. This causes all DNS resolution to fail for fixed-output derivations that use the Guile-based git-fetch builder (e.g. git-fetch/lfs), since they rely on slirp4netns for network access in the build chroot. Derivations using builtin:git-download are unaffected because they run in the daemon process itself, which has full network access. Change-Id: Ib73e69a8760e74eb8141dd0408c27aa8b3001e37 Signed-off-by: Ludovic Courtès Merges: #6959 --- nix/libstore/build.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 3071c8ef10..9bdf0a78ae 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1972,11 +1972,15 @@ static void prepareSlirpChrootAction(SpawnContext & sctx) } /* Limit /etc to containing just /etc/resolv.conf and /etc/hosts, and - read-only at that */ + read-only at that. Resolve symlinks in the source path so that + bindMount sees a regular file and bind-mounts it, rather than + copying a symlink whose target may not exist in the chroot + (e.g. /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf + with /run/ being empty in the chroot). */ Strings etcFiles = { "/etc/resolv.conf", "/etc/hosts" }; for(auto & i : etcFiles) { if(pathExists(i)) { - ctx.filesInChroot[i] = i; + ctx.filesInChroot[i] = canonPath(i, true); ctx.readOnlyFilesInChroot.insert(i); } }