From 546f98dace5c3569211caf392c9dde06a20aa7b0 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Mon, 19 Feb 2018 18:44:30 +0200 Subject: [PATCH] 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. --- src/libutil/hash.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 11e3c9dca..75e476755 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -189,7 +189,8 @@ Hash::Hash(const std::string & s, HashType type) else if (size == base64Len()) { 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); }