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
+30
View File
@@ -124,6 +124,20 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
const void* dict,size_t dictSize)
{
U32 const version = ZSTD_isLegacy(src, compressedSize);
char x;
/* Avoid passing NULL to legacy decoding. */
if (dst == NULL) {
assert(dstCapacity == 0);
dst = &x;
}
if (src == NULL) {
assert(compressedSize == 0);
src = &x;
}
if (dict == NULL) {
assert(dictSize == 0);
dict = &x;
}
(void)dst; (void)dstCapacity; (void)dict; (void)dictSize; /* unused when ZSTD_LEGACY_SUPPORT >= 8 */
switch(version)
{
@@ -287,6 +301,12 @@ MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
const void* dict, size_t dictSize)
{
char x;
/* Avoid passing NULL to legacy decoding. */
if (dict == NULL) {
assert(dictSize == 0);
dict = &x;
}
DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u", newVersion);
if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
switch(newVersion)
@@ -346,6 +366,16 @@ MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U
MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
ZSTD_outBuffer* output, ZSTD_inBuffer* input)
{
static char x;
/* Avoid passing NULL to legacy decoding. */
if (output->dst == NULL) {
assert(output->size == 0);
output->dst = &x;
}
if (input->src == NULL) {
assert(input->size == 0);
input->src = &x;
}
DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u", version);
switch(version)
{
+2
View File
@@ -14,6 +14,7 @@
******************************************/
#include <stddef.h> /* size_t, ptrdiff_t */
#include "zstd_v01.h"
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -2118,6 +2119,7 @@ size_t ZSTDv01_decompressContinue(ZSTDv01_Dctx* dctx, void* dst, size_t maxDstSi
}
ctx->phase = 1;
ctx->expected = ZSTD_blockHeaderSize;
if (ZSTDv01_isError(rSize)) return rSize;
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
return rSize;
}
+2 -14
View File
@@ -11,6 +11,7 @@
#include <stddef.h> /* size_t, ptrdiff_t */
#include "zstd_v02.h"
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -71,20 +72,6 @@ extern "C" {
#include <string.h> /* memcpy */
/******************************************
* Compiler-specific
******************************************/
#if defined(__GNUC__)
# define MEM_STATIC static __attribute__((unused))
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# define MEM_STATIC static inline
#elif defined(_MSC_VER)
# define MEM_STATIC static __inline
#else
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
#endif
/****************************************************************
* Basic Types
*****************************************************************/
@@ -3431,6 +3418,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi
}
ctx->phase = 1;
ctx->expected = ZSTD_blockHeaderSize;
if (ZSTD_isError(rSize)) return rSize;
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
return rSize;
}
+2 -14
View File
@@ -11,6 +11,7 @@
#include <stddef.h> /* size_t, ptrdiff_t */
#include "zstd_v03.h"
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -72,20 +73,6 @@ extern "C" {
#include <string.h> /* memcpy */
/******************************************
* Compiler-specific
******************************************/
#if defined(__GNUC__)
# define MEM_STATIC static __attribute__((unused))
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# define MEM_STATIC static inline
#elif defined(_MSC_VER)
# define MEM_STATIC static __inline
#else
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
#endif
/****************************************************************
* Basic Types
*****************************************************************/
@@ -3071,6 +3058,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi
}
ctx->phase = 1;
ctx->expected = ZSTD_blockHeaderSize;
if (ZSTD_isError(rSize)) return rSize;
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
return rSize;
}
+4 -2
View File
@@ -16,6 +16,7 @@
#include <string.h> /* memcpy */
#include "zstd_v04.h"
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -3209,6 +3210,7 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* ctx, void* dst, size_t maxDstSi
}
ctx->stage = ZSTDds_decodeBlockHeader;
ctx->expected = ZSTD_blockHeaderSize;
if (ZSTD_isError(rSize)) return rSize;
ctx->previousDstEnd = (char*)dst + rSize;
return rSize;
}
@@ -3536,8 +3538,8 @@ static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDs
unsigned ZBUFFv04_isError(size_t errorCode) { return ERR_isError(errorCode); }
const char* ZBUFFv04_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
size_t ZBUFFv04_recommendedDInSize() { return BLOCKSIZE + 3; }
size_t ZBUFFv04_recommendedDOutSize() { return BLOCKSIZE; }
size_t ZBUFFv04_recommendedDInSize(void) { return BLOCKSIZE + 3; }
size_t ZBUFFv04_recommendedDOutSize(void) { return BLOCKSIZE; }
+1
View File
@@ -3600,6 +3600,7 @@ size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t maxDstSi
}
dctx->stage = ZSTDv05ds_decodeBlockHeader;
dctx->expected = ZSTDv05_blockHeaderSize;
if (ZSTDv05_isError(rSize)) return rSize;
dctx->previousDstEnd = (char*)dst + rSize;
return rSize;
}
+2
View File
@@ -14,6 +14,7 @@
#include <stddef.h> /* size_t, ptrdiff_t */
#include <string.h> /* memcpy */
#include <stdlib.h> /* malloc, free, qsort */
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -3736,6 +3737,7 @@ size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapac
}
dctx->stage = ZSTDds_decodeBlockHeader;
dctx->expected = ZSTDv06_blockHeaderSize;
if (ZSTDv06_isError(rSize)) return rSize;
dctx->previousDstEnd = (char*)dst + rSize;
return rSize;
}
+2 -1
View File
@@ -24,6 +24,7 @@
#define HUFv07_STATIC_LINKING_ONLY /* HUFv07_TABLELOG_ABSOLUTEMAX */
#define ZSTDv07_STATIC_LINKING_ONLY
#include "../common/compiler.h"
#include "../common/error_private.h"
@@ -4006,8 +4007,8 @@ size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapac
}
dctx->stage = ZSTDds_decodeBlockHeader;
dctx->expected = ZSTDv07_blockHeaderSize;
dctx->previousDstEnd = (char*)dst + rSize;
if (ZSTDv07_isError(rSize)) return rSize;
dctx->previousDstEnd = (char*)dst + rSize;
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
return rSize;
}