From a9b20ae6a38073afe91ae2b7d789ddfb7dabade8 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Thu, 6 Jul 2017 00:21:01 +0000 Subject: Use zlib for CRC-32 Previously, we had our own CRC that was almost but not quite like zlib's implementation. However, * it hasn't been subjected to the same rigor with regard to error-detection properties and * it may not even get used, depending upon whether zlib happens to get loaded before or after liberasurecode. Now, we'll use zlib's CRC-32 when writing new frags, while still tolerating frags that were created with the old implementation. Change-Id: Ib5ea2a830c7c23d66bf2ca404a3eb84ad00c5bc5 Closes-Bug: 1666320 --- src/Makefile.am | 7 ++++--- src/erasurecode.c | 21 ++++++++++++++++++--- src/erasurecode_helpers.c | 5 +++-- src/utils/chksum/crc32.c | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8312dd0..693809e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,9 +34,10 @@ liberasurecode_la_SOURCES = \ liberasurecode_la_CPPFLAGS = -Werror @GCOV_FLAGS@ liberasurecode_la_LIBADD = \ - builtin/null_code/libnullcode.la -lpthread -lm @GCOV_LDFLAGS@ \ - builtin/xor_codes/libXorcode.la -lpthread -lm @GCOV_LDFLAGS@ \ - builtin/rs_vand/liberasurecode_rs_vand.la -lpthread -lm @GCOV_LDFLAGS@ + builtin/null_code/libnullcode.la \ + builtin/xor_codes/libXorcode.la \ + builtin/rs_vand/liberasurecode_rs_vand.la \ + -lpthread -lm -lz @GCOV_LDFLAGS@ # Version format (C - A).(A).(R) for C:R:A input liberasurecode_la_LDFLAGS = -rpath '$(libdir)' -version-info @LIBERASURECODE_VERSION_INFO@ diff --git a/src/erasurecode.c b/src/erasurecode.c index d4a06c2..20da457 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -26,6 +26,7 @@ * vi: set noai tw=79 ts=4 sw=4: */ +#include #include "assert.h" #include "list.h" #include "erasurecode.h" @@ -1063,9 +1064,17 @@ int liberasurecode_get_fragment_metadata(char *fragment, uint32_t stored_chksum = fragment_hdr->meta.chksum[0]; char *fragment_data = get_data_ptr_from_fragment(fragment); uint64_t fragment_size = fragment_hdr->meta.size; - computed_chksum = crc32(0, fragment_data, fragment_size); + computed_chksum = crc32(0, (unsigned char *) fragment_data, fragment_size); if (stored_chksum != computed_chksum) { - fragment_metadata->chksum_mismatch = 1; + // Try again with our "alternative" crc32; see + // https://bugs.launchpad.net/liberasurecode/+bug/1666320 + computed_chksum = liberasurecode_crc32_alt( + 0, fragment_data, fragment_size); + if (stored_chksum != computed_chksum) { + fragment_metadata->chksum_mismatch = 1; + } else { + fragment_metadata->chksum_mismatch = 0; + } } else { fragment_metadata->chksum_mismatch = 0; } @@ -1095,7 +1104,13 @@ int is_invalid_fragment_header(fragment_header_t *header) stored_csum = get_metadata_chksum((char *) header); if (NULL == stored_csum) return 1; /* can't verify, possibly crc32 call error */ - csum = crc32(0, &header->meta, sizeof(fragment_metadata_t)); + csum = crc32(0, (unsigned char *) &header->meta, sizeof(fragment_metadata_t)); + if (*stored_csum == csum) { + return 0; + } + // Else, try again with our "alternative" crc32; see + // https://bugs.launchpad.net/liberasurecode/+bug/1666320 + csum = liberasurecode_crc32_alt(0, &header->meta, sizeof(fragment_metadata_t)); return (*stored_csum != csum); } diff --git a/src/erasurecode_helpers.c b/src/erasurecode_helpers.c index fd14298..4a49786 100644 --- a/src/erasurecode_helpers.c +++ b/src/erasurecode_helpers.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "erasurecode_backend.h" #include "erasurecode_helpers.h" #include "erasurecode_helpers_ext.h" @@ -474,7 +475,7 @@ inline int set_checksum(ec_checksum_type_t ct, char *buf, int blocksize) switch(header->meta.chksum_type) { case CHKSUM_CRC32: - header->meta.chksum[0] = crc32(0, data, blocksize); + header->meta.chksum[0] = crc32(0, (unsigned char *) data, blocksize); break; case CHKSUM_MD5: break; @@ -512,7 +513,7 @@ inline int set_metadata_chksum(char *buf) return -1; } - header->metadata_chksum = crc32(0, &header->meta, + header->metadata_chksum = crc32(0, (unsigned char *) &header->meta, sizeof(fragment_metadata_t)); return 0; } diff --git a/src/utils/chksum/crc32.c b/src/utils/chksum/crc32.c index 6bc844d..b11dec9 100644 --- a/src/utils/chksum/crc32.c +++ b/src/utils/chksum/crc32.c @@ -89,7 +89,7 @@ static int crc32_tab[] = { }; int -crc32(int crc, const void *buf, size_t size) +liberasurecode_crc32_alt(int crc, const void *buf, size_t size) { const char *p; -- cgit v1.2.1