summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nix/libstore/build.cc36
1 files changed, 35 insertions, 1 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index d23c0944a48..67ebfe2f146 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -1301,6 +1301,34 @@ void replaceValidPath(const Path & storePath, const Path tmpPath)
1301MakeError(NotDeterministic, BuildError) 1301MakeError(NotDeterministic, BuildError)
1302 1302
1303 1303
1304/* Recursively make the file permissions of a path safe for exposure to
1305 arbitrary users, but without canonicalising its permissions, timestamp, and
1306 user. Throw an exception if a file type that isn't explicitly known to be
1307 safe is found. */
1308static void secureFilePerms(Path path)
1309{
1310 struct stat st;
1311 if (lstat(path.c_str(), &st)) return;
1312
1313 switch(st.st_mode & S_IFMT) {
1314 case S_IFLNK:
1315 return;
1316
1317 case S_IFDIR:
1318 for (auto & i : readDirectory(path)) {
1319 secureFilePerms(path + "/" + i.name);
1320 }
1321 /* FALLTHROUGH */
1322
1323 case S_IFREG:
1324 chmod(path.c_str(), (st.st_mode & ~S_IFMT) & ~(S_ISUID | S_ISGID | S_IWOTH));
1325 break;
1326
1327 default:
1328 throw Error(format("file `%1%' has an unsupported type") % path);
1329 }
1330}
1331
1304void DerivationGoal::buildDone() 1332void DerivationGoal::buildDone()
1305{ 1333{
1306 trace("build done"); 1334 trace("build done");
@@ -1372,8 +1400,14 @@ void DerivationGoal::buildDone()
1372 build failures. */ 1400 build failures. */
1373 if (useChroot && buildMode == bmNormal) 1401 if (useChroot && buildMode == bmNormal)
1374 foreach (PathSet::iterator, i, missingPaths) 1402 foreach (PathSet::iterator, i, missingPaths)
1375 if (pathExists(chrootRootDir + *i)) 1403 if (pathExists(chrootRootDir + *i)) {
1404 try {
1405 secureFilePerms(chrootRootDir + *i);
1376 rename((chrootRootDir + *i).c_str(), i->c_str()); 1406 rename((chrootRootDir + *i).c_str(), i->c_str());
1407 } catch(Error & e) {
1408 printMsg(lvlError, e.msg());
1409 }
1410 }
1377 1411
1378 if (diskFull) 1412 if (diskFull)
1379 printMsg(lvlError, "note: build failure may have been caused by lack of free disk space"); 1413 printMsg(lvlError, "note: build failure may have been caused by lack of free disk space");