Skip to content

Commit fcaf06d

Browse files
Check that dest is valid for decompression (#3555)
* add check for valid dest buffer and fuzz on random dest ptr when malloc 0 * add uptrval to linux-kernel * remove bin files * get rid of uptrval * restrict max pointer value check to platforms where sizeof(size_t) == sizeof(void*)
1 parent 7b828aa commit fcaf06d

File tree

6 files changed

+32
-3
lines changed

6 files changed

+32
-3
lines changed

lib/decompress/zstd_decompress_block.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,9 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
21122112
ip += seqHSize;
21132113
srcSize -= seqHSize;
21142114

2115-
RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
2115+
RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
2116+
RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall,
2117+
"invalid dst");
21162118

21172119
/* If we could potentially have long offsets, or we might want to use the prefetch decoder,
21182120
* compute information about the share of long offsets, and the maximum nbAdditionalBits.

tests/fuzz/block_decompress.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* decompression function to ensure the decompressor never crashes.
1414
*/
1515

16+
#include "fuzz_data_producer.h"
1617
#define ZSTD_STATIC_LINKING_ONLY
1718

1819
#include <stddef.h>
@@ -28,11 +29,12 @@ static size_t bufSize = 0;
2829
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
2930
{
3031
size_t const neededBufSize = ZSTD_BLOCKSIZE_MAX;
32+
FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
3133

3234
/* Allocate all buffers and contexts if not already allocated */
3335
if (neededBufSize > bufSize) {
3436
free(rBuf);
35-
rBuf = FUZZ_malloc(neededBufSize);
37+
rBuf = FUZZ_malloc_rand(neededBufSize, producer);
3638
bufSize = neededBufSize;
3739
}
3840
if (!dctx) {
@@ -42,6 +44,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
4244
ZSTD_decompressBegin(dctx);
4345
ZSTD_decompressBlock(dctx, rBuf, neededBufSize, src, size);
4446

47+
FUZZ_dataProducer_free(producer);
48+
4549
#ifndef STATEFUL_FUZZING
4650
ZSTD_freeDCtx(dctx); dctx = NULL;
4751
#endif

tests/fuzz/fuzz_data_producer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* You may select, at your option, one of the above-listed licenses.
99
*/
1010

11+
#include "fuzz_helpers.h"
1112
#include "fuzz_data_producer.h"
1213

1314
struct FUZZ_dataProducer_s{

tests/fuzz/fuzz_data_producer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include <stdio.h>
2525
#include <stdlib.h>
2626

27-
#include "fuzz_helpers.h"
2827

2928
/* Struct used for maintaining the state of the data */
3029
typedef struct FUZZ_dataProducer_s FUZZ_dataProducer_t;

tests/fuzz/fuzz_helpers.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ void* FUZZ_malloc(size_t size)
2323
return NULL;
2424
}
2525

26+
void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer)
27+
{
28+
if (size > 0) {
29+
void* const mem = malloc(size);
30+
FUZZ_ASSERT(mem);
31+
return mem;
32+
} else {
33+
uintptr_t ptr = 0;
34+
/* Add +- 1M 50% of the time */
35+
if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
36+
FUZZ_dataProducer_int32Range(producer, -1000000, 1000000);
37+
return (void*)ptr;
38+
}
39+
40+
}
41+
2642
int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size)
2743
{
2844
if (size == 0) {

tests/fuzz/fuzz_helpers.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "fuzz.h"
2020
#include "xxhash.h"
2121
#include "zstd.h"
22+
#include "fuzz_data_producer.h"
2223
#include <stdint.h>
2324
#include <stdio.h>
2425
#include <stdlib.h>
@@ -62,6 +63,12 @@ extern "C" {
6263
*/
6364
void* FUZZ_malloc(size_t size);
6465

66+
/**
67+
* malloc except returns random pointer for zero sized data and FUZZ_ASSERT
68+
* that malloc doesn't fail.
69+
*/
70+
void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer);
71+
6572
/**
6673
* memcmp but accepts NULL.
6774
*/

0 commit comments

Comments
 (0)