Closed Crispy-fried-chicken closed 2 months ago
Hi. As you probably realize, your (mostly automated?) report is confusing. The HHVM commit you link to fixes many unrelated issues against different pieces of their own and upstream code they bundled. This includes changes to code they got from our crypt_blowfish indirectly via upstream PHP, which had also made changes. And then you claim "Out-of-bounds Write" in this issue's title, but also "Insufficient Information" in the issue description.
What helps is your reference to BF_crypt
. HHVM is adding the ((unsigned int)(setting[7 + 22 - 1] - 0x20) >= 0x60)
check below:
if (count < min ||
BF_decode(data.binary.salt, &setting[7], 16) ||
((unsigned int)(setting[7 + 22 - 1] - 0x20) >= 0x60)
) {
__set_errno(EINVAL);
return NULL;
}
The question is why. Later in the function, we have:
output[7 + 22 - 1] = BF_itoa64[(int)
BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
The purpose of this piece is to reset the unused salt bits, to produce a canonical salt string in the output even if the input had non-zeroes in the unused bits.
We have (int)setting[7 + 22 - 1] - 0x20
in here, which is used to index BF_atoi64
and so could result in an out-of-bounds read. Except that this character is also part of what BF_decode
decodes, and we're checking its return value right in this same if
above, and it's supposed to indicate error if that character was out of range.
So there should be no issue here, and I'm puzzled as to why HHVM patched it as an issue - maybe just to silence a static analyzer that didn't look inside or figure out BF_decode
?
I'll double-check before closing this issue.
why HHVM patched it as an issue - maybe just to silence a static analyzer that didn't look inside or figure out
BF_decode
?
This is indeed hard to figure out. We pass 16 as byte size to it, and it could be unclear that 22 characters is still within that size. But it is. And indeed we check for out of range characters in there and return non-zero, which the if
above catches:
#define BF_safe_atoi64(dst, src) \
{ \
tmp = (unsigned char)(src); \
if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
So HHVM's added check looks redundant to me, at least in our codebase here (I didn't check full context in theirs).
could result in an out-of-bounds read.
Indeed, https://hhvm.com/blog/2020/11/12/security-update.html says "out of bounds read in crypt()". But it is unclear whether they refer to this specific change - they're making more changes to crypt() in another function. So maybe they actually fixed an issue specific to them, perhaps in those other changes.
Hi, we have detected that your project may be vulnerable to Insufficient Information in the function of
BF_crypt
in the file ofcrypt_blowfish.c
. It shares similarities to a recent CVE disclosure CVE-2020-1916 in the https://github.com/facebook/hhvm. The source vulnerability information is as follows:Would you help to check if this bug is true? If it's true, I'd like to open a PR for that if necessary. Thank you for your effort and patience!