diff options
author | Théophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com> | 2024-04-11 13:41:49 +0200 |
---|---|---|
committer | K900 <me@0upti.me> | 2024-04-11 15:43:58 +0300 |
commit | 07b627cc6d1224df75ea2d4979c4c83bb67392f1 (patch) | |
tree | d4c46eb2c75b55154f78d9ef1cb1ffbbe84edf72 /src/libstore/build | |
parent | aeee22e5a17404b10dd14b5289e302eaf546e1aa (diff) |
Merge pull request #10456 from NixOS/fixpermdeniedbind
Fix adding symlink to the sandbox paths
(cherry-picked from commit da1e977bf48cff2a635034c85e7c13878e38efc2)
Change-Id: I221c85a38180800ec6552d2e86a88df48398fad8
Diffstat (limited to 'src/libstore/build')
-rw-r--r-- | src/libstore/build/local-derivation-goal.cc | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index c373ed27f..588fe33ba 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -389,21 +389,33 @@ void LocalDerivationGoal::cleanupPostOutputsRegisteredModeNonCheck() #if __linux__ static void doBind(const Path & source, const Path & target, bool optional = false) { debug("bind mounting '%1%' to '%2%'", source, target); - struct stat st; - if (stat(source.c_str(), &st) == -1) { - if (optional && errno == ENOENT) + + auto bindMount = [&]() { + if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1) + throw SysError("bind mount from '%1%' to '%2%' failed", source, target); + }; + + auto maybeSt = maybeLstat(source); + if (!maybeSt) { + if (optional) return; else throw SysError("getting attributes of path '%1%'", source); } - if (S_ISDIR(st.st_mode)) + auto st = *maybeSt; + + if (S_ISDIR(st.st_mode)) { createDirs(target); - else { + bindMount(); + } else if (S_ISLNK(st.st_mode)) { + // Symlinks can (apparently) not be bind-mounted, so just copy it + createDirs(dirOf(target)); + copyFile(source, target, /* andDelete */ false); + } else { createDirs(dirOf(target)); writeFile(target, ""); + bindMount(); } - if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1) - throw SysError("bind mount from '%1%' to '%2%' failed", source, target); }; #endif |