Skip to content
Closed
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
23 changes: 23 additions & 0 deletions projects/libdeflate/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM gcr.io/oss-fuzz-base/base-builder

RUN apt-get update && apt-get install -y --no-install-recommends cmake

RUN git clone --depth 1 https://github.com/ebiggers/libdeflate.git

WORKDIR libdeflate
COPY build.sh $SRC/
COPY *.c $SRC/
40 changes: 40 additions & 0 deletions projects/libdeflate/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash -eu

# Build libdeflate
cmake . -DCMAKE_BUILD_TYPE=Release \
-DLIBDEFLATE_BUILD_STATIC_LIB=ON \
-DLIBDEFLATE_BUILD_SHARED_LIB=OFF \
-DLIBDEFLATE_BUILD_GZIP=OFF \
-DCMAKE_C_FLAGS="$CFLAGS" \
-DCMAKE_CXX_FLAGS="$CXXFLAGS"
make -j$(nproc) deflate_static

# Build deflate_decompress fuzzer (uses guarded allocations for buffer OOB detection)
$CC $CFLAGS -Iinclude -c $SRC/deflate_decompress_fuzzer.c -o deflate_decompress_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE deflate_decompress_fuzzer.o \
libdeflate.a -o $OUT/deflate_decompress_fuzzer

# Build gzip_decompress fuzzer
$CC $CFLAGS -Iinclude -c $SRC/gzip_decompress_fuzzer.c -o gzip_decompress_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE gzip_decompress_fuzzer.o \
libdeflate.a -o $OUT/gzip_decompress_fuzzer

# Build zlib_decompress fuzzer
$CC $CFLAGS -Iinclude -c $SRC/zlib_decompress_fuzzer.c -o zlib_decompress_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE zlib_decompress_fuzzer.o \
libdeflate.a -o $OUT/zlib_decompress_fuzzer

# Build deflate_compress fuzzer (round-trip: compress then decompress)
$CC $CFLAGS -Iinclude -c $SRC/deflate_compress_fuzzer.c -o deflate_compress_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE deflate_compress_fuzzer.o \
libdeflate.a -o $OUT/deflate_compress_fuzzer

# Build adler32/crc32 checksum fuzzers
$CC $CFLAGS -Iinclude -c $SRC/checksum_fuzzer.c -o checksum_fuzzer.o
$CXX $CXXFLAGS $LIB_FUZZING_ENGINE checksum_fuzzer.o \
libdeflate.a -o $OUT/checksum_fuzzer

# Seed corpora: real DEFLATE/gzip compressed files make great seeds
zip $OUT/deflate_decompress_fuzzer_seed_corpus.zip \
$(find $SRC/libdeflate -name "*.gz" 2>/dev/null | head -20) 2>/dev/null || true
cp $OUT/deflate_decompress_fuzzer_seed_corpus.zip $OUT/gzip_decompress_fuzzer_seed_corpus.zip 2>/dev/null || true
49 changes: 49 additions & 0 deletions projects/libdeflate/checksum_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <libdeflate.h>
#include <stdint.h>
#include <stdlib.h>

/*
* Fuzz adler32 and crc32 checksum computation.
* These are incremental APIs that should handle any input cleanly.
*/
int LLVMFuzzerTestOneInput(const uint8_t *in, size_t insize)
{
uint32_t adler, crc;

/* Test adler32 incremental update */
adler = libdeflate_adler32(1, in, insize);
/* Test split — first half then second half */
if (insize >= 2) {
adler = libdeflate_adler32(1, in, insize / 2);
adler = libdeflate_adler32(adler, in + insize / 2,
insize - insize / 2);
}

/* Test crc32 incremental update */
crc = libdeflate_crc32(0, in, insize);
if (insize >= 2) {
crc = libdeflate_crc32(0, in, insize / 2);
crc = libdeflate_crc32(crc, in + insize / 2,
insize - insize / 2);
}

(void)adler;
(void)crc;
return 0;
}
76 changes: 76 additions & 0 deletions projects/libdeflate/deflate_compress_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <libdeflate.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/*
* Fuzz DEFLATE compression + round-trip decompression.
* This exercises both the compressor and verifies the output is valid.
*/
int LLVMFuzzerTestOneInput(const uint8_t *in, size_t insize)
{
struct libdeflate_compressor *c;
struct libdeflate_decompressor *d;
uint8_t *cbuf, *dbuf;
size_t cbuf_size, actual_out_nbytes;
int level;

/* Pick compression level from first byte if available */
if (insize == 0)
return 0;
level = (in[0] % 12) + 1;
in++;
insize--;

c = libdeflate_alloc_compressor(level);
if (!c)
return 0;

cbuf_size = libdeflate_deflate_compress_bound(c, insize);
cbuf = malloc(cbuf_size);
if (!cbuf) {
libdeflate_free_compressor(c);
return 0;
}

size_t cbytes = libdeflate_deflate_compress(c, in, insize, cbuf, cbuf_size);
libdeflate_free_compressor(c);

if (cbytes == 0) {
free(cbuf);
return 0;
}

/* Round-trip: decompress and verify we get back the original data */
dbuf = malloc(insize + 1);
if (!dbuf) {
free(cbuf);
return 0;
}

d = libdeflate_alloc_decompressor();
if (d) {
libdeflate_deflate_decompress(d, cbuf, cbytes,
dbuf, insize, &actual_out_nbytes);
libdeflate_free_decompressor(d);
}
free(cbuf);
free(dbuf);
return 0;
}
42 changes: 42 additions & 0 deletions projects/libdeflate/deflate_decompress_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <assert.h>
#include <libdeflate.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/* Fuzz DEFLATE decompression with a large output buffer. */
int LLVMFuzzerTestOneInput(const uint8_t *in, size_t insize)
{
size_t outsize_avail = 3 * insize + 4096;
uint8_t *out;
struct libdeflate_decompressor *d;

out = malloc(outsize_avail);
if (!out)
return 0;

d = libdeflate_alloc_decompressor();
if (d) {
libdeflate_deflate_decompress(d, in, insize,
out, outsize_avail, NULL);
libdeflate_free_decompressor(d);
}
free(out);
return 0;
}
39 changes: 39 additions & 0 deletions projects/libdeflate/gzip_decompress_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <libdeflate.h>
#include <stdint.h>
#include <stdlib.h>

/* Fuzz gzip decompression. */
int LLVMFuzzerTestOneInput(const uint8_t *in, size_t insize)
{
size_t outsize_avail = 3 * insize + 4096;
uint8_t *out;
struct libdeflate_decompressor *d;

out = malloc(outsize_avail);
if (!out)
return 0;

d = libdeflate_alloc_decompressor();
if (d) {
libdeflate_gzip_decompress(d, in, insize, out, outsize_avail, NULL);
libdeflate_free_decompressor(d);
}
free(out);
return 0;
}
14 changes: 14 additions & 0 deletions projects/libdeflate/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
homepage: "https://github.com/ebiggers/libdeflate"
language: c
primary_contact: "ebiggers3@gmail.com"
main_repo: "https://github.com/ebiggers/libdeflate"
auto_ccs:
- "ebiggers3@gmail.com"
fuzzing_engines:
- libfuzzer
- afl
- honggfuzz
sanitizers:
- address
- undefined
- memory
39 changes: 39 additions & 0 deletions projects/libdeflate/zlib_decompress_fuzzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

#include <libdeflate.h>
#include <stdint.h>
#include <stdlib.h>

/* Fuzz zlib-format decompression. */
int LLVMFuzzerTestOneInput(const uint8_t *in, size_t insize)
{
size_t outsize_avail = 3 * insize + 4096;
uint8_t *out;
struct libdeflate_decompressor *d;

out = malloc(outsize_avail);
if (!out)
return 0;

d = libdeflate_alloc_decompressor();
if (d) {
libdeflate_zlib_decompress(d, in, insize, out, outsize_avail, NULL);
libdeflate_free_decompressor(d);
}
free(out);
return 0;
}