mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 12:10:59 +01:00
* Take the position of self-references into account when computing
content hashes. This is to prevent a rewrite of
...HASH...HASH...
and
...HASH...0000...
(where HASH is the randomly generated prefix) from hashing to the
same value. This would happen because they would both resolve to
...0000...0000... Exploiting this into a security hole is left as
an exercise to the reader ;-)
This commit is contained in:
parent
049e74ccf6
commit
f06a9429cf
1 changed files with 20 additions and 7 deletions
|
|
@ -35,14 +35,12 @@ bool PathHash::isNull() const
|
||||||
|
|
||||||
bool PathHash::operator ==(const PathHash & hash2) const
|
bool PathHash::operator ==(const PathHash & hash2) const
|
||||||
{
|
{
|
||||||
debug("foo");
|
|
||||||
return rep == hash2.rep;
|
return rep == hash2.rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PathHash::operator <(const PathHash & hash2) const
|
bool PathHash::operator <(const PathHash & hash2) const
|
||||||
{
|
{
|
||||||
debug("bar");
|
|
||||||
return rep < hash2.rep;
|
return rep < hash2.rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +69,8 @@ struct CopySource : RestoreSource
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
string rewriteHashes(string s, const HashRewrites & rewrites)
|
static string rewriteHashes(string s, const HashRewrites & rewrites,
|
||||||
|
vector<int> & positions)
|
||||||
{
|
{
|
||||||
for (HashRewrites::const_iterator i = rewrites.begin();
|
for (HashRewrites::const_iterator i = rewrites.begin();
|
||||||
i != rewrites.end(); ++i)
|
i != rewrites.end(); ++i)
|
||||||
|
|
@ -83,6 +82,7 @@ string rewriteHashes(string s, const HashRewrites & rewrites)
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
while ((j = s.find(from, j)) != string::npos) {
|
while ((j = s.find(from, j)) != string::npos) {
|
||||||
debug(format("rewriting @ %1%") % j);
|
debug(format("rewriting @ %1%") % j);
|
||||||
|
positions.push_back(j);
|
||||||
s.replace(j, to.size(), to);
|
s.replace(j, to.size(), to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,14 +93,26 @@ string rewriteHashes(string s, const HashRewrites & rewrites)
|
||||||
|
|
||||||
PathHash hashModulo(string s, const PathHash & modulus)
|
PathHash hashModulo(string s, const PathHash & modulus)
|
||||||
{
|
{
|
||||||
|
vector<int> positions;
|
||||||
|
|
||||||
if (!modulus.isNull()) {
|
if (!modulus.isNull()) {
|
||||||
/* Zero out occurences of `modulus'. */
|
/* Zero out occurences of `modulus'. */
|
||||||
HashRewrites rewrites;
|
HashRewrites rewrites;
|
||||||
rewrites[modulus] = PathHash(); /* = null hash */
|
rewrites[modulus] = PathHash(); /* = null hash */
|
||||||
s = rewriteHashes(s, rewrites);
|
s = rewriteHashes(s, rewrites, positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PathHash(hashString(htSHA256, s));
|
string positionPrefix;
|
||||||
|
|
||||||
|
for (vector<int>::iterator i = positions.begin();
|
||||||
|
i != positions.end(); ++i)
|
||||||
|
positionPrefix += (format("|%1%") % *i).str();
|
||||||
|
|
||||||
|
positionPrefix += "||";
|
||||||
|
|
||||||
|
debug(format("positions %1%") % positionPrefix);
|
||||||
|
|
||||||
|
return PathHash(hashString(htSHA256, positionPrefix + s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -118,7 +130,8 @@ Path addToStore(const Path & srcPath, const PathHash & selfHash)
|
||||||
if (!selfHash.isNull()) {
|
if (!selfHash.isNull()) {
|
||||||
HashRewrites rewrites;
|
HashRewrites rewrites;
|
||||||
rewrites[selfHash] = newHash;
|
rewrites[selfHash] = newHash;
|
||||||
sink.s = rewriteHashes(sink.s, rewrites);
|
vector<int> positions;
|
||||||
|
sink.s = rewriteHashes(sink.s, rewrites, positions);
|
||||||
PathHash newHash2 = hashModulo(sink.s, newHash);
|
PathHash newHash2 = hashModulo(sink.s, newHash);
|
||||||
assert(newHash2 == newHash);
|
assert(newHash2 == newHash);
|
||||||
debug(format("newHash2 %1%") % newHash2.toString());
|
debug(format("newHash2 %1%") % newHash2.toString());
|
||||||
|
|
@ -137,7 +150,7 @@ int main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
verbosity = (Verbosity) ((int) 10);
|
verbosity = (Verbosity) ((int) 10);
|
||||||
|
|
||||||
Path p = addToStore("./bar", PathHash(parseHash32(htSHA256, "8myr6ajc52b5sky7iplgz8jv703ljc0q")));
|
Path p = addToStore("./foo", PathHash(parseHash32(htSHA256, "8myr6ajc52b5sky7iplgz8jv703ljc0q")));
|
||||||
|
|
||||||
cout << p << endl;
|
cout << p << endl;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue