* Remove write permission from output paths after they have been built.

* Point $HOME to a non-existing path when building to prevent certain tools (such as 
  wget) from falling back on /etc/passwd to locate the home directory (which we 
  don't want them to look at since it's not declared as an input).
This commit is contained in:
Eelco Dolstra 2003-08-22 20:12:44 +00:00
parent 56b98c3857
commit a88144215c
3 changed files with 52 additions and 6 deletions

View File

@ -131,6 +131,14 @@ FSId normaliseFState(FSId id, FSIdSet pending)
value. */ value. */
env["PATH"] = "/path-not-set"; env["PATH"] = "/path-not-set";
/* Set HOME to a non-existing path to prevent certain programs from using
/etc/passwd (or NIS, or whatever) to locate the home directory (for
example, wget looks for ~/.wgetrc). I.e., these tools use /etc/passwd
if HOME is not set, but they will just assume that the settings file
they are looking for does not exist if HOME is set but points to some
non-existing path. */
env["HOME"] = "/homeless-shelter";
/* Build the environment. */ /* Build the environment. */
for (StringPairs::iterator i = fs.derive.env.begin(); for (StringPairs::iterator i = fs.derive.env.begin();
i != fs.derive.env.end(); i++) i != fs.derive.env.end(); i++)
@ -178,7 +186,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
msg(lvlChatty, format("fast build succesful")); msg(lvlChatty, format("fast build succesful"));
/* Check whether the output paths were created, and grep each /* Check whether the output paths were created, and grep each
output path to determine what other paths it references. */ output path to determine what other paths it references. Also make all
output paths read-only. */
StringSet usedPaths; StringSet usedPaths;
for (DeriveOutputs::iterator i = fs.derive.outputs.begin(); for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
i != fs.derive.outputs.end(); i++) i != fs.derive.outputs.end(); i++)
@ -188,10 +197,12 @@ FSId normaliseFState(FSId id, FSIdSet pending)
throw Error(format("path `%1%' does not exist") % path); throw Error(format("path `%1%' does not exist") % path);
nfFS.slice.roots.insert(path); nfFS.slice.roots.insert(path);
makePathReadOnly(path);
/* For this output path, find the references to other paths contained /* For this output path, find the references to other paths contained
in it. */ in it. */
Strings refPaths = filterReferences(path, Strings refPaths = filterReferences(path,
Strings(allPaths.begin(), allPaths.end())); Strings(allPaths.begin(), allPaths.end()));
/* Construct a slice element for this output path. */ /* Construct a slice element for this output path. */
SliceElem elem; SliceElem elem;

View File

@ -106,13 +106,13 @@ bool pathExists(const string & path)
} }
void deletePath(string path) void deletePath(const string & path)
{ {
msg(lvlVomit, format("deleting path `%1%'") % path); msg(lvlVomit, format("deleting path `%1%'") % path);
struct stat st; struct stat st;
if (lstat(path.c_str(), &st)) if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path %1%") % path); throw SysError(format("getting attributes of path `%1%'") % path);
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
Strings names; Strings names;
@ -128,12 +128,44 @@ void deletePath(string path)
closedir(dir); /* !!! close on exception */ closedir(dir); /* !!! close on exception */
/* Make the directory writable. */
if (!(st.st_mode & S_IWUSR)) {
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
throw SysError(format("making `%1%' writable"));
}
for (Strings::iterator i = names.begin(); i != names.end(); i++) for (Strings::iterator i = names.begin(); i != names.end(); i++)
deletePath(path + "/" + *i); deletePath(path + "/" + *i);
} }
if (remove(path.c_str()) == -1) if (remove(path.c_str()) == -1)
throw SysError(format("cannot unlink %1%") % path); throw SysError(format("cannot unlink `%1%'") % path);
}
void makePathReadOnly(const string & path)
{
struct stat st;
if (lstat(path.c_str(), &st))
throw SysError(format("getting attributes of path `%1%'") % path);
if (st.st_mode & S_IWUSR) {
if (chmod(path.c_str(), st.st_mode & ~S_IWUSR) == -1)
throw SysError(format("making `%1%' read-only"));
}
if (S_ISDIR(st.st_mode)) {
DIR * dir = opendir(path.c_str());
struct dirent * dirent;
while (errno = 0, dirent = readdir(dir)) {
string name = dirent->d_name;
if (name == "." || name == "..") continue;
makePathReadOnly(path + "/" + name);
}
closedir(dir); /* !!! close on exception */
}
} }

View File

@ -67,7 +67,10 @@ bool pathExists(const string & path);
/* Delete a path; i.e., in the case of a directory, it is deleted /* Delete a path; i.e., in the case of a directory, it is deleted
recursively. Don't use this at home, kids. */ recursively. Don't use this at home, kids. */
void deletePath(string path); void deletePath(const string & path);
/* Make a path read-only recursively. */
void makePathReadOnly(const string & path);
/* Messages. */ /* Messages. */