Home | History | Annotate | Line # | Download | only in ossfuzz
      1 // SPDX-License-Identifier: 0BSD
      2 
      3 ///////////////////////////////////////////////////////////////////////////////
      4 //
      5 /// \file       fuzz_encode_stream.c
      6 /// \brief      Fuzz test program for .xz encoding
      7 //
      8 //  Authors:    Maksym Vatsyk
      9 //              Lasse Collin
     10 //
     11 ///////////////////////////////////////////////////////////////////////////////
     12 
     13 #include <inttypes.h>
     14 #include <stdlib.h>
     15 #include <stdio.h>
     16 #include "lzma.h"
     17 #include "fuzz_common.h"
     18 
     19 
     20 extern int
     21 LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
     22 {
     23 	if (inbuf_size == 0) {
     24 		fprintf(stderr, "no input data provided\n");
     25 		return 0;
     26 	}
     27 
     28 	// Set the LZMA options based on the first input byte. The fuzzer
     29 	// will learn through its mutational genetic algorithm with the
     30 	// code coverage feedback that the first byte must be one of the
     31 	// values with a switch case label. This allows us to have one fuzz
     32 	// target cover many critical code paths so the fuzz resources can
     33 	// be used efficiently.
     34 	uint32_t preset_level;
     35 	const uint8_t decider = inbuf[0];
     36 
     37 	switch (decider) {
     38 	case 0:
     39 	case 1:
     40 	case 5:
     41 		preset_level = (uint32_t)decider;
     42 		break;
     43 	case 6:
     44 		preset_level = 0 | LZMA_PRESET_EXTREME;
     45 		break;
     46 	case 7:
     47 		preset_level = 3 | LZMA_PRESET_EXTREME;
     48 		break;
     49 	default:
     50 		return 0;
     51 	}
     52 
     53 	// Initialize lzma_options with the above preset level
     54 	lzma_options_lzma opt_lzma;
     55 	if (lzma_lzma_preset(&opt_lzma, preset_level)){
     56 		fprintf(stderr, "lzma_lzma_preset() failed\n");
     57 		abort();
     58 	}
     59 
     60 	// Set the filter chain as only LZMA2.
     61 	lzma_filter filters[2] = {
     62 		{
     63 			.id = LZMA_FILTER_LZMA2,
     64 			.options = &opt_lzma,
     65 		}, {
     66 			.id = LZMA_VLI_UNKNOWN,
     67 		}
     68 	};
     69 
     70 	// initialize empty LZMA stream
     71 	lzma_stream strm = LZMA_STREAM_INIT;
     72 
     73 	// Initialize the stream encoder using the above
     74 	// stream, filter chain and CRC64.
     75 	lzma_ret ret = lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC64);
     76 	if (ret != LZMA_OK) {
     77 		fprintf(stderr, "lzma_stream_encoder() failed (%d)\n", ret);
     78 		abort();
     79 	}
     80 
     81 	fuzz_code(&strm, inbuf  + 1, inbuf_size - 1);
     82 
     83 	// Free the allocated memory.
     84 	lzma_end(&strm);
     85 	return 0;
     86 }
     87