aboutsummaryrefslogtreecommitdiff
path: root/tests/ossfuzz
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ossfuzz')
-rw-r--r--tests/ossfuzz/Makefile3
-rw-r--r--tests/ossfuzz/config/fuzz_decode_stream.options1
-rw-r--r--tests/ossfuzz/config/fuzz_lzma.dict34
-rw-r--r--tests/ossfuzz/fuzz_common.h16
-rw-r--r--tests/ossfuzz/fuzz_decode_alone.c15
-rw-r--r--tests/ossfuzz/fuzz_decode_stream.c15
-rw-r--r--tests/ossfuzz/fuzz_encode_stream.c38
7 files changed, 66 insertions, 56 deletions
diff --git a/tests/ossfuzz/Makefile b/tests/ossfuzz/Makefile
index 008cd7df..a25bd0db 100644
--- a/tests/ossfuzz/Makefile
+++ b/tests/ossfuzz/Makefile
@@ -8,5 +8,8 @@ all: $(FUZZ_TARGET_BINS)
$(CXX) $(CXXFLAGS) $(LIB_FUZZING_ENGINE) $(<:.c=.o) -o $(OUT)/$@ \
../../src/liblzma/.libs/liblzma.a ;
+# The generated binaries are not removed, just the object files. The
+# binaries are created to the $(OUT) directory and must be removed by the
+# fuzzing framework.
clean:
rm -f *.o
diff --git a/tests/ossfuzz/config/fuzz_decode_stream.options b/tests/ossfuzz/config/fuzz_decode_stream.options
index 61799737..d8f9edba 100644
--- a/tests/ossfuzz/config/fuzz_decode_stream.options
+++ b/tests/ossfuzz/config/fuzz_decode_stream.options
@@ -1,3 +1,2 @@
[libfuzzer]
-max_len = 4096
dict = fuzz_xz.dict
diff --git a/tests/ossfuzz/config/fuzz_lzma.dict b/tests/ossfuzz/config/fuzz_lzma.dict
index 38d4da3e..82a2b871 100644
--- a/tests/ossfuzz/config/fuzz_lzma.dict
+++ b/tests/ossfuzz/config/fuzz_lzma.dict
@@ -1,22 +1,20 @@
# first 5 header bytes of .lzma archives based on the info from
-# https://github.com/tukaani-project/xz/blob/master/doc/lzma-file-format.txt
+# /doc/lzma-file-format.txt
-# byte 0 value (properties=0x5d) is created by encoding
-# common values (lc=3, lp=0, pb=2) using the algorithm,
-# described in the documentation above
+# byte 0 is created by encoding LZMA property values (lc, lp, pb)
+# using the algorithm described in the documentation above.
-
-# compression preset 1 (dictionary size = 0x00100000)
+# lc=3, lp=0, pb=2 and dictionary size = 0x00100000
"\x5d\x00\x00\x10\x00"
-# compression preset 2 (dictionary size = 0x00200000)
-"\x5d\x00\x00\x20\x00"
-# compression preset 3, 4 (dictionary size = 0x00400000)
-"\x5d\x00\x00\x40\x00"
-# compression preset 5, 6 (dictionary size = 0x00800000)
-"\x5d\x00\x00\x80\x00"
-# compression preset 7 (dictionary size = 0x01000000)
-"\x5d\x00\x00\x00\x01"
-# compression preset 8 (dictionary size = 0x02000000)
-"\x5d\x00\x00\x00\x02"
-# compression preset 9 (dictionary size = 0x04000000)
-"\x5d\x00\x00\x00\x04"
+
+# lc=3, lp=1, pb=3 and dictionary size = 0x00100000
+"\x93\x00\x00\x10\x00"
+
+# lc=2, lp=2, pb=4 and dictionary size = 0x00100000
+"\xc8\x00\x00\x10\x00"
+
+# lc=1, lp=3, pb=1 and dictionary size = 0x00200000
+"\x49\x00\x00\x20\x00"
+
+# lc=0, lp=4, pb=0 and dictionary size = 0x00200000
+"\x24\x00\x00\x20\x00"
diff --git a/tests/ossfuzz/fuzz_common.h b/tests/ossfuzz/fuzz_common.h
index ce3f9345..14742f2e 100644
--- a/tests/ossfuzz/fuzz_common.h
+++ b/tests/ossfuzz/fuzz_common.h
@@ -1,9 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
//
-/// \file fuzz_decode_auto.c
-/// \brief Fuzz test program for liblzma lzma_auto_decoder()
+/// \file fuzz_common.h
+/// \brief Common macros and functions needed by the fuzz targets
//
-// Author: Maksym Vatsyk
+// Authors: Maksym Vatsyk
+// Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
@@ -21,13 +22,12 @@
#define MEM_LIMIT (300 << 20) // 300 MiB
-// Output buffer for decompressed data. This is write only; nothing cares
-// about the actual data written here.
-static uint8_t outbuf[4096];
-
-
static void
fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) {
+ // Output buffer for decompressed data. This is write only; nothing
+ // cares about the actual data written here.
+ uint8_t outbuf[4096];
+
// Give the whole input buffer at once to liblzma.
// Output buffer isn't initialized as liblzma only writes to it.
stream->next_in = inbuf;
diff --git a/tests/ossfuzz/fuzz_decode_alone.c b/tests/ossfuzz/fuzz_decode_alone.c
index d07874bc..2fb7bc09 100644
--- a/tests/ossfuzz/fuzz_decode_alone.c
+++ b/tests/ossfuzz/fuzz_decode_alone.c
@@ -1,11 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
//
-/// \file fuzz_decode_auto.c
-/// \brief Fuzz test program for liblzma lzma_auto_decoder()
+/// \file fuzz_decode_alone.c
+/// \brief Fuzz test program for liblzma .lzma decoding
//
-// Author: Maksym Vatsyk
-//
-// Based on Lasse Collin's original fuzzer for liblzma
+// Authors: Maksym Vatsyk
+// Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
@@ -25,11 +24,13 @@ LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
lzma_stream strm = LZMA_STREAM_INIT;
// Initialize a LZMA alone decoder using the memory usage limit
// defined in fuzz_common.h
- if (lzma_alone_decoder(&strm, MEM_LIMIT) != LZMA_OK) {
+ lzma_ret ret = lzma_alone_decoder(&strm, MEM_LIMIT);
+
+ if (ret != LZMA_OK) {
// This should never happen unless the system has
// no free memory or address space to allow the small
// allocations that the initialization requires.
- fprintf(stderr, "lzma_alone_decoder() failed\n");
+ fprintf(stderr, "lzma_alone_decoder() failed (%d)\n", ret);
abort();
}
diff --git a/tests/ossfuzz/fuzz_decode_stream.c b/tests/ossfuzz/fuzz_decode_stream.c
index 1da8ecb3..e06613e3 100644
--- a/tests/ossfuzz/fuzz_decode_stream.c
+++ b/tests/ossfuzz/fuzz_decode_stream.c
@@ -1,10 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file fuzz_decode_stream.c
-/// \brief Fuzz test program for liblzma
-//
-// Author: Lasse Collin
+/// \brief Fuzz test program for single threaded .xz decoding
//
+// Authors: Lasse Collin
+// Maksym Vatsyk
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
@@ -22,7 +22,7 @@ extern int
LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
{
lzma_stream strm = LZMA_STREAM_INIT;
- // Initialize a LZMA alone decoder using the memory usage limit
+ // Initialize a LZMA decoder using the memory usage limit
// defined in fuzz_common.h
//
// Enable support for concatenated .xz files which is used when
@@ -34,13 +34,14 @@ LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
// The flag LZMA_IGNORE_CHECK doesn't disable verification of
// header CRC32 values. Those checks are disabled when liblzma is
// built with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
+ lzma_ret ret = lzma_stream_decoder(&strm, MEM_LIMIT,
+ LZMA_CONCATENATED | LZMA_IGNORE_CHECK);
- if (lzma_stream_decoder(&strm, MEM_LIMIT,
- LZMA_CONCATENATED | LZMA_IGNORE_CHECK) != LZMA_OK) {
+ if (ret != LZMA_OK) {
// This should never happen unless the system has
// no free memory or address space to allow the small
// allocations that the initialization requires.
- fprintf(stderr, "lzma_stream_decoder() failed\n");
+ fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret);
abort();
}
diff --git a/tests/ossfuzz/fuzz_encode_stream.c b/tests/ossfuzz/fuzz_encode_stream.c
index 8ae8780e..f5770baa 100644
--- a/tests/ossfuzz/fuzz_encode_stream.c
+++ b/tests/ossfuzz/fuzz_encode_stream.c
@@ -1,11 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file fuzz_encode_stream.c
-/// \brief Fuzz test program for liblzma lzma_stream_encoder() w/ LZMA2
+/// \brief Fuzz test program for .xz encoding
//
-// Author: Maksym Vatsyk
-//
-// Based on Lasse Collin's original fuzzer for liblzma
+// Authors: Maksym Vatsyk
+// Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
@@ -27,9 +26,15 @@ LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
return 0;
}
- // set LZMA preset level based on the first input byte
+ // Set the LZMA options based on the first input byte. The fuzzer
+ // will learn through its mutational genetic algorithm with the
+ // code coverage feedback that the first byte must be one of the
+ // values with a switch case label. This allows us to have one fuzz
+ // target cover many critical code paths so the fuzz resources can
+ // be used efficiently.
uint32_t preset_level;
- uint8_t decider = inbuf[0];
+ const uint8_t decider = inbuf[0];
+
switch (decider) {
case 0:
case 1:
@@ -53,21 +58,24 @@ LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
abort();
}
- // Initialize filter chain for lzma_stream_decoder() call
- // Use single LZMA2 filter for encoding
- lzma_filter filters[2];
- filters[0].id = LZMA_FILTER_LZMA2;
- filters[0].options = &opt_lzma;
- filters[1].id = LZMA_VLI_UNKNOWN;
+ // Set the filter chain as only LZMA2.
+ lzma_filter filters[2] = {
+ {
+ .id = LZMA_FILTER_LZMA2,
+ .options = &opt_lzma,
+ }, {
+ .id = LZMA_VLI_UNKNOWN,
+ }
+ };
// initialize empty LZMA stream
lzma_stream strm = LZMA_STREAM_INIT;
// Initialize the stream encoder using the above
// stream, filter chain and CRC64.
- if (lzma_stream_encoder(&strm,
- filters, LZMA_CHECK_CRC64) != LZMA_OK) {
- fprintf(stderr, "lzma_stream_encoder() failed\n");
+ lzma_ret ret = lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC64);
+ if (ret != LZMA_OK) {
+ fprintf(stderr, "lzma_stream_encoder() failed (%d)\n", ret);
abort();
}