* Also for convenience, change the ownership of the build output even

in case of failure.
This commit is contained in:
Eelco Dolstra 2006-12-08 00:19:50 +00:00
parent 096194ab29
commit d3fe6ab024

View file

@ -862,9 +862,17 @@ void DerivationGoal::buildDone()
pid_t savedPid = pid; pid_t savedPid = pid;
int status = pid.wait(true); int status = pid.wait(true);
debug(format("builder process for `%1%' finished") % drvPath);
/* So the child is gone now. */ /* So the child is gone now. */
worker.childTerminated(savedPid); worker.childTerminated(savedPid);
/* Close the read side of the logger pipe. */
logPipe.readSide.close();
/* Close the log file. */
fdLogFile.close();
/* When running under a build user, make sure that all processes /* When running under a build user, make sure that all processes
running under that uid are gone. This is to prevent a running under that uid are gone. This is to prevent a
malicious user from leaving behind a process that keeps files malicious user from leaving behind a process that keeps files
@ -873,13 +881,35 @@ void DerivationGoal::buildDone()
if (buildUser.enabled()) if (buildUser.enabled())
buildUser.kill(); buildUser.kill();
/* Close the read side of the logger pipe. */ /* Some cleanup per path. We do this here and not in
logPipe.readSide.close(); computeClosure() for convenience when the build has failed. */
for (DerivationOutputs::iterator i = drv.outputs.begin();
i != drv.outputs.end(); ++i)
{
Path path = i->second.path;
if (!pathExists(path)) continue;
/* Close the log file. */ struct stat st;
fdLogFile.close(); if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path `%1%'") % path);
debug(format("builder process for `%1%' finished") % drvPath); #ifndef __CYGWIN__
/* Check that the output is not group or world writable, as
that means that someone else can have interfered with the
build. Also, the output should be owned by the build
user. */
if ((st.st_mode & (S_IWGRP | S_IWOTH)) ||
(buildUser.enabled() && st.st_uid != buildUser.getUID()))
throw Error(format("suspicious ownership or permission on `%1%'; rejecting this build output") % path);
#endif
/* Gain ownership of the build result using the setuid wrapper
if we're not root. If we *are* root, then
canonicalisePathMetaData() will take care of this later
on. */
if (buildUser.enabled() && !amPrivileged())
getOwnership(path);
}
/* Check the exit status. */ /* Check the exit status. */
if (!statusOk(status)) { if (!statusOk(status)) {
@ -1560,22 +1590,6 @@ void DerivationGoal::computeClosure()
% path % algo % printHash(h) % printHash(h2)); % path % algo % printHash(h) % printHash(h2));
} }
#ifndef __CYGWIN__
/* Check that the output is not group or world writable, as
that means that someone else can have interfered with the
build. Also, the output should be owned by the build
user. */
if ((st.st_mode & (S_IWGRP | S_IWOTH)) ||
(buildUser.enabled() && st.st_uid != buildUser.getUID()))
throw Error(format("suspicious ownership or permission on `%1%'; rejecting this build output") % path);
#endif
if (buildUser.enabled() && !amPrivileged())
/* Call the setuid helper to change ownership from the
build user to our uid. If we *are* root, then
canonicalisePathMetaData() will take care of this. */
getOwnership(path);
/* Get rid of all weird permissions. */ /* Get rid of all weird permissions. */
canonicalisePathMetaData(path); canonicalisePathMetaData(path);