Merge pull request #18852 from azat/bit-flip-check

Do not check bit flips for big buffers (since the size can be corrupted)
This commit is contained in:
alexey-milovidov 2021-01-08 22:41:33 +03:00 committed by GitHub
commit 9c6d945afc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -67,20 +67,25 @@ static void validateChecksum(char * data, size_t size, const Checksum expected_c
buf[pos / 8] ^= 1 << pos % 8;
};
/// Check if the difference caused by single bit flip in data.
for (size_t bit_pos = 0; bit_pos < size * 8; ++bit_pos)
/// If size is too huge, then this may be caused by corruption.
/// And anyway this is pretty heavy, so avoid burning too much CPU here.
if (size < (1ULL << 20))
{
flip_bit(data, bit_pos);
auto checksum_of_data_with_flipped_bit = CityHash_v1_0_2::CityHash128(data, size);
if (expected_checksum == checksum_of_data_with_flipped_bit)
/// Check if the difference caused by single bit flip in data.
for (size_t bit_pos = 0; bit_pos < size * 8; ++bit_pos)
{
message << ". The mismatch is caused by single bit flip in data block at byte " << (bit_pos / 8) << ", bit " << (bit_pos % 8) << ". "
<< message_hardware_failure;
throw Exception(message.str(), ErrorCodes::CHECKSUM_DOESNT_MATCH);
}
flip_bit(data, bit_pos);
flip_bit(data, bit_pos); /// Restore
auto checksum_of_data_with_flipped_bit = CityHash_v1_0_2::CityHash128(data, size);
if (expected_checksum == checksum_of_data_with_flipped_bit)
{
message << ". The mismatch is caused by single bit flip in data block at byte " << (bit_pos / 8) << ", bit " << (bit_pos % 8) << ". "
<< message_hardware_failure;
throw Exception(message.str(), ErrorCodes::CHECKSUM_DOESNT_MATCH);
}
flip_bit(data, bit_pos); /// Restore
}
}
/// Check if the difference caused by single bit flip in stored checksum.