libutil: Fix invalid assert on decoding base64 hashes

The assertion is broken because there is no one-to-one mapping from
length of a base64 string to the length of the output.

E.g.

"1q69lz7Empb06nzfkj651413n9icx0njmyr3xzq1j9q=" results in a 32-byte output.
"1q69lz7Empb06nzfkj651413n9icx0njmyr3xzq1j9qy" results in a 33-byte output.

To reproduce, evaluate:

builtins.derivationStrict {
    name = "0";
    builder = "0";
    system = "0";
    outputHashAlgo = "sha256";
    outputHash = "1q69lz7Empb06nzfkj651413n9icx0njmyr3xzq1j9qy";
}

Found by afl-fuzz.
This commit is contained in:
Tuomas Tynkkynen 2018-02-19 18:44:30 +02:00
parent 4ea9707591
commit 546f98dace

View file

@ -189,7 +189,8 @@ Hash::Hash(const std::string & s, HashType type)
else if (size == base64Len()) { else if (size == base64Len()) {
auto d = base64Decode(std::string(s, pos)); auto d = base64Decode(std::string(s, pos));
assert(d.size() == hashSize); if (d.size() != hashSize)
throw BadHash("invalid base-64 hash '%s'", s);
memcpy(hash, d.data(), hashSize); memcpy(hash, d.data(), hashSize);
} }