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