Stop suppressing pointer-overflow UBSAN errors

* Remove all pointer-overflow suppressions from our UBSAN builds/tests.
* Add `ZSTD_ALLOW_POINTER_OVERFLOW_ATTR` macro to suppress
  pointer-overflow at a per-function level. This is a superior approach
  because it also applies to users who build zstd with UBSAN.
* Add `ZSTD_wrappedPtr{Diff,Add,Sub}()` that use these suppressions.
  The end goal is to only tag these functions with
  `ZSTD_ALLOW_POINTER_OVERFLOW`. But we can start by annoting functions
  that rely on pointer overflow, and gradually transition to using
  these.
* Add `ZSTD_maybeNullPtrAdd()` to simplify pointer addition when the
  pointer may be `NULL`.
* Fix all the fuzzer issues that came up. I'm sure there will be a lot
  more, but these are the ones that came up within a few minutes of
  running the fuzzers, and while running GitHub CI.
This commit is contained in:
Nick Terrell
2023-09-28 17:35:05 -04:00
committed by Nick Terrell
parent 3daed7017a
commit 43118da8a7
23 changed files with 252 additions and 103 deletions
+1 -1
View File
@@ -732,7 +732,7 @@ generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
}
} while (((!info.useDict) && (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0);
{ BYTE* const dictEnd = info.dictContent + info.dictContentSize;
{ BYTE* const dictEnd = ZSTD_maybeNullPtrAdd(info.dictContent, info.dictContentSize);
size_t j;
for (j = 0; j < matchLen; j++) {
if ((U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart) < offset) {
+3 -5
View File
@@ -250,10 +250,10 @@ def build_parser(args):
action='store_true',
help='Enable UBSAN')
parser.add_argument(
'--enable-ubsan-pointer-overflow',
'--disable-ubsan-pointer-overflow',
dest='ubsan_pointer_overflow',
action='store_true',
help='Enable UBSAN pointer overflow check (known failure)')
action='store_false',
help='Disable UBSAN pointer overflow check (known failure)')
parser.add_argument(
'--enable-msan', dest='msan', action='store_true', help='Enable MSAN')
parser.add_argument(
@@ -383,8 +383,6 @@ def build_parser(args):
raise RuntimeError('MSAN may not be used with any other sanitizers')
if args.msan_track_origins and not args.msan:
raise RuntimeError('--enable-msan-track-origins requires MSAN')
if args.ubsan_pointer_overflow and not args.ubsan:
raise RuntimeError('--enable-ubsan-pointer-overflow requires UBSAN')
if args.sanitize_recover and not args.sanitize:
raise RuntimeError('--enable-sanitize-recover but no sanitizers used')
+1 -1
View File
@@ -116,7 +116,7 @@ static size_t decodeSequences(void* dst, size_t nbSequences,
}
}
for (; j < matchLength; ++j) {
op[j] = op[j - generatedSequences[i].offset];
op[j] = op[(ptrdiff_t)(j - generatedSequences[i].offset)];
}
op += j;
FUZZ_ASSERT(generatedSequences[i].matchLength == j + k);
+3 -1
View File
@@ -328,7 +328,7 @@ static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize,
if (seqs[i].offset != 0) {
for (j = 0; j < seqs[i].matchLength; ++j)
dst[j] = dst[j - seqs[i].offset];
dst[j] = dst[(ptrdiff_t)(j - seqs[i].offset)];
dst += seqs[i].matchLength;
src += seqs[i].matchLength;
size -= seqs[i].matchLength;
@@ -3684,11 +3684,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* Test with block delimiters roundtrip */
seqsSize = ZSTD_generateSequences(cctx, seqs, srcSize, src, srcSize);
CHECK_Z(seqsSize);
FUZ_decodeSequences(decoded, seqs, seqsSize, src, srcSize, ZSTD_sf_explicitBlockDelimiters);
assert(!memcmp(CNBuffer, compressedBuffer, srcSize));
/* Test no block delimiters roundtrip */
seqsSize = ZSTD_mergeBlockDelimiters(seqs, seqsSize);
CHECK_Z(seqsSize);
FUZ_decodeSequences(decoded, seqs, seqsSize, src, srcSize, ZSTD_sf_noBlockDelimiters);
assert(!memcmp(CNBuffer, compressedBuffer, srcSize));