diff --git a/tests/ossfuzz/fuzz_decode_alone.c b/tests/ossfuzz/fuzz_decode_alone.c index e11aa6be..79f3c64f 100644 --- a/tests/ossfuzz/fuzz_decode_alone.c +++ b/tests/ossfuzz/fuzz_decode_alone.c @@ -21,21 +21,26 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) { lzma_stream strm = LZMA_STREAM_INIT; + strm.next_in = inbuf; + strm.avail_in = inbuf_size; - // Initialize a LZMA alone decoder using the memory usage limit - // defined in fuzz_common.h - lzma_ret ret = lzma_alone_decoder(&strm, MEM_LIMIT); + lzma_ret ret; - 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 (%d)\n", ret); - abort(); + for (int i = 0; i < 3; ++i) { + 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 (%d)\n", + ret); + abort(); + } + + fuzz_code(&strm, strm.next_in, strm.avail_in); } - fuzz_code(&strm, inbuf, inbuf_size); - // Free the allocated memory. lzma_end(&strm); return 0; diff --git a/tests/ossfuzz/fuzz_decode_stream.c b/tests/ossfuzz/fuzz_decode_stream.c index c5675056..550c4118 100644 --- a/tests/ossfuzz/fuzz_decode_stream.c +++ b/tests/ossfuzz/fuzz_decode_stream.c @@ -21,32 +21,44 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) { lzma_stream strm = LZMA_STREAM_INIT; + strm.next_in = inbuf; + strm.avail_in = inbuf_size; - // Initialize a .xz decoder using the memory usage limit - // defined in fuzz_common.h - // - // Enable support for concatenated .xz files which is used when - // decompressing regular .xz files (instead of data embedded inside - // some other file format). Integrity checks on the uncompressed - // data are ignored to make fuzzing more effective (incorrect check - // values won't prevent the decoder from processing more input). - // - // 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); + lzma_ret ret; - 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 (%d)\n", ret); - abort(); + for (int i = 0; i < 3; ++i) { + // Initialize a .xz decoder using the memory usage limit + // defined in fuzz_common.h + // + // After the first two iterations, enable support for + // concatenated .xz files which is used when decompressing + // regular .xz files (instead of data embedded inside some + // other file format). This way the first iteration won't + // consume all the input until the input is invalid. + // + // Integrity checks on the uncompressed data are ignored to + // make fuzzing more effective (incorrect check values won't + // prevent the decoder from processing more input). + // + // 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. + ret = lzma_stream_decoder(&strm, MEM_LIMIT, LZMA_IGNORE_CHECK + | (i >= 2 ? LZMA_CONCATENATED : 0)); + + 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 (%d)\n", + ret); + abort(); + } + + fuzz_code(&strm, inbuf, inbuf_size); } - fuzz_code(&strm, inbuf, inbuf_size); - // Free the allocated memory. lzma_end(&strm); diff --git a/tests/ossfuzz/fuzz_decode_stream_mt.c b/tests/ossfuzz/fuzz_decode_stream_mt.c index 23ea9765..6beb68c5 100644 --- a/tests/ossfuzz/fuzz_decode_stream_mt.c +++ b/tests/ossfuzz/fuzz_decode_stream_mt.c @@ -20,27 +20,37 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size) { lzma_stream strm = LZMA_STREAM_INIT; + strm.next_in = inbuf; + strm.avail_in = inbuf_size; lzma_mt mt = { - .flags = LZMA_CONCATENATED | LZMA_IGNORE_CHECK, + .flags = /*LZMA_CONCATENATED |*/ LZMA_IGNORE_CHECK, .threads = 2, .timeout = 0, .memlimit_threading = MEM_LIMIT / 2, .memlimit_stop = MEM_LIMIT, }; - lzma_ret ret = lzma_stream_decoder_mt(&strm, &mt); + lzma_ret ret; - 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_mt() failed (%d)\n", ret); - abort(); + for (int i = 0; i < 3; ++i) { + if (i == 2) + mt.flags |= LZMA_CONCATENATED; + + ret = lzma_stream_decoder_mt(&strm, &mt); + + 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_mt() " + "failed (%d)\n", ret); + abort(); + } + + fuzz_code(&strm, strm.next_in, strm.avail_in); } - fuzz_code(&strm, inbuf, inbuf_size); - lzma_end(&strm); return 0;