Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion tests/fuzz/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ FUZZ_TARGETS := \
sequence_compression_api \
seekable_roundtrip \
huf_round_trip \
huf_decompress
huf_decompress \
frame_header_cross_format

all: libregression.a $(FUZZ_TARGETS)

Expand Down Expand Up @@ -238,6 +239,9 @@ huf_round_trip: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o

huf_decompress: $(FUZZ_HEADERS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o
$(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o $(LIB_FUZZING_ENGINE) -o $@

frame_header_cross_format: $(FUZZ_HEADERS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_frame_header_cross_format.o
$(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_frame_header_cross_format.o $(LIB_FUZZING_ENGINE) -o $@

libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o
$(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o
Expand Down
74 changes: 74 additions & 0 deletions tests/fuzz/frame_header_cross_format.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/

/**
* This fuzz target validates that ZSTD_getFrameHeader_advanced() is consistent between
* ZSTD_f_zstd1 format and ZSTD_f_zstd1_magicless format.
*/

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include "fuzz_helpers.h"
#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
#include "fuzz_data_producer.h"

#include <stdio.h>
void prettyPrint(ZSTD_frameHeader* header) {
printf("ZSTD_frameHeader:\n");
printf(" frameContentSize: %llu\n", header->frameContentSize);
printf(" windowSize: %llu\n", header->windowSize);
printf(" blockSizeMax: %u\n", header->blockSizeMax);
printf(" frameType: %s\n", header->frameType == ZSTD_frame ? "ZSTD_frame" : "ZSTD_skippableFrame");
printf(" headerSize: %u\n", header->headerSize);
printf(" dictID: %u\n", header->dictID);
printf(" checksumFlag: %u\n", header->checksumFlag);
printf(" _reserved1: %u\n", header->_reserved1);
printf(" _reserved2: %u\n", header->_reserved2);
}

int LLVMFuzzerTestOneInput(const uint8_t *magiclessSrc, size_t magiclessSize)
{
const int zstd_magic = ZSTD_MAGICNUMBER;
FUZZ_ASSERT(sizeof(zstd_magic) == 4); // assume sizeof(int) == 4
const size_t standardSize = sizeof(zstd_magic) + magiclessSize;
void* standardSrc = FUZZ_malloc(standardSize);
memcpy(standardSrc, &zstd_magic, sizeof(zstd_magic)); // assume fuzzing on little-endian machine
memcpy(standardSrc + sizeof(zstd_magic), magiclessSrc, magiclessSize);

ZSTD_frameHeader header_magicless;
ZSTD_frameHeader header_standard;

// TODO: use fuzz data producer here
memset(&header_magicless, 0xAB, sizeof(ZSTD_frameHeader));
memset(&header_standard, 0xCD, sizeof(ZSTD_frameHeader));

const size_t magicless_ret = ZSTD_getFrameHeader_advanced(
&header_magicless, magiclessSrc, magiclessSize, ZSTD_f_zstd1_magicless);
const size_t standard_ret = ZSTD_getFrameHeader_advanced(
&header_standard, standardSrc, standardSize, ZSTD_f_zstd1);

// If magicless frame header is valid, then standard frame header should match
if (magicless_ret == 0) {
FUZZ_ASSERT(standard_ret == 0);

// headerSize is not expected to be equal between formats
FUZZ_ASSERT(header_magicless.headerSize + sizeof(zstd_magic) == header_standard.headerSize);

// Assert that all other fields are equal
header_magicless.headerSize = 0;
header_standard.headerSize = 0;
FUZZ_ASSERT(memcmp(&header_magicless, &header_standard, sizeof(ZSTD_frameHeader)) == 0);
}

free(standardSrc);
return 0;
}
1 change: 1 addition & 0 deletions tests/fuzz/fuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def __init__(self, input_type, frame_type=FrameType.ZSTD):
'seekable_roundtrip': TargetInfo(InputType.RAW_DATA),
'huf_round_trip': TargetInfo(InputType.RAW_DATA),
'huf_decompress': TargetInfo(InputType.RAW_DATA),
'frame_header_cross_format': TargetInfo(InputType.RAW_DATA),
}
TARGETS = list(TARGET_INFO.keys())
ALL_TARGETS = TARGETS + ['all']
Expand Down