diff options
| -rw-r--r-- | nix/libstore/build.cc | 36 |
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) | |||
| 1301 | MakeError(NotDeterministic, BuildError) | 1301 | MakeError(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. */ | ||
| 1308 | static 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 | |||
| 1304 | void DerivationGoal::buildDone() | 1332 | void 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"); |
