* Special derivation attribute `allowedReferences' that causes Nix to
check that the references of the output of a derivation are in the specified set. For instance, allowedReferences = []; specifies that the output cannot have any references. (This is useful, for instance, for the generation of bootstrap binaries for stdenv-linux, which must not have any references for purity). It could also be used to guard against undesired runtime dependencies, e.g., {gcc, dynlib}: derivation { ... allowedReferences = [dynlib]; } says that the output can refer to the path of `dynlib' but not `gcc'. A `forbiddedReferences' attribute would be more useful for this, though.
This commit is contained in:
parent
daa8f85fcd
commit
6a67556f71
|
@ -1349,6 +1349,26 @@ void DerivationGoal::startBuilder()
|
|||
}
|
||||
|
||||
|
||||
/* Parse a list of reference specifiers. Each element must either be
|
||||
a store path, or the symbolic name of the output of the derivation
|
||||
(such as `out'). */
|
||||
PathSet parseReferenceSpecifiers(const Derivation & drv, string attr)
|
||||
{
|
||||
PathSet result;
|
||||
Paths paths = tokenizeString(attr);
|
||||
for (Strings::iterator i = paths.begin(); i != paths.end(); ++i) {
|
||||
if (isStorePath(*i))
|
||||
result.insert(*i);
|
||||
else if (drv.outputs.find(*i) != drv.outputs.end())
|
||||
result.insert(drv.outputs.find(*i)->second.path);
|
||||
else throw Error(
|
||||
format("derivation contains an illegal reference specifier `%1%'")
|
||||
% *i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DerivationGoal::computeClosure()
|
||||
{
|
||||
map<Path, PathSet> allReferences;
|
||||
|
@ -1442,6 +1462,17 @@ void DerivationGoal::computeClosure()
|
|||
|
||||
allReferences[path] = references;
|
||||
|
||||
/* If the derivation specifies an `allowedReferences'
|
||||
attribute (containing a list of paths that the output may
|
||||
refer to), check that all references are in that list. !!!
|
||||
allowedReferences should really be per-output. */
|
||||
if (drv.env.find("allowedReferences") != drv.env.end()) {
|
||||
PathSet allowed = parseReferenceSpecifiers(drv, drv.env["allowedReferences"]);
|
||||
for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
|
||||
if (allowed.find(*i) == allowed.end())
|
||||
throw Error(format("output is not allowed to refer to path `%1%'") % *i);
|
||||
}
|
||||
|
||||
/* Hash the contents of the path. The hash is stored in the
|
||||
database so that we can verify later on whether nobody has
|
||||
messed with the store. !!! inefficient: it would be nice
|
||||
|
|
Loading…
Reference in a new issue