(root)/
xz-5.4.5/
tests/
ossfuzz/
fuzz.c
       1  ///////////////////////////////////////////////////////////////////////////////
       2  //
       3  /// \file       fuzz.c
       4  /// \brief      Fuzz test program for liblzma
       5  //
       6  //  Author:     Lasse Collin
       7  //
       8  //  This file has been put into the public domain.
       9  //  You can do whatever you want with this file.
      10  //
      11  ///////////////////////////////////////////////////////////////////////////////
      12  
      13  #include <inttypes.h>
      14  #include <stdlib.h>
      15  #include <stdio.h>
      16  #include "lzma.h"
      17  
      18  
      19  // Output buffer for decompressed data. This is write only; nothing cares
      20  // about the actual data written here.
      21  static uint8_t outbuf[4096];
      22  
      23  
      24  extern int
      25  LLVMFuzzerTestOneInput(const uint8_t *inbuf, size_t inbuf_size)
      26  {
      27  	// Some header values can make liblzma allocate a lot of RAM
      28  	// (up to about 4 GiB with liblzma 5.2.x). We set a limit here to
      29  	// prevent extreme allocations when fuzzing.
      30  	const uint64_t memlimit = 300 << 20; // 300 MiB
      31  
      32  	// Initialize a .xz decoder using the above memory usage limit.
      33  	// Enable support for concatenated .xz files which is used when
      34  	// decompressing regular .xz files (instead of data embedded inside
      35  	// some other file format). Integrity checks on the uncompressed
      36  	// data are ignored to make fuzzing more effective (incorrect check
      37  	// values won't prevent the decoder from processing more input).
      38  	//
      39  	// The flag LZMA_IGNORE_CHECK doesn't disable verification of header
      40  	// CRC32 values. Those checks are disabled when liblzma is built
      41  	// with the #define FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION.
      42  	lzma_stream strm = LZMA_STREAM_INIT;
      43  	lzma_ret ret = lzma_stream_decoder(&strm, memlimit,
      44  			LZMA_CONCATENATED | LZMA_IGNORE_CHECK);
      45  	if (ret != LZMA_OK) {
      46  		// This should never happen unless the system has
      47  		// no free memory or address space to allow the small
      48  		// allocations that the initialization requires.
      49  		fprintf(stderr, "lzma_stream_decoder() failed (%d)\n", ret);
      50  		abort();
      51  	}
      52  
      53  	// Give the whole input buffer at once to liblzma.
      54  	// Output buffer isn't initialized as liblzma only writes to it.
      55  	strm.next_in = inbuf;
      56  	strm.avail_in = inbuf_size;
      57  	strm.next_out = outbuf;
      58  	strm.avail_out = sizeof(outbuf);
      59  
      60  	while ((ret = lzma_code(&strm, LZMA_FINISH)) == LZMA_OK) {
      61  		if (strm.avail_out == 0) {
      62  			// outbuf became full. We don't care about the
      63  			// uncompressed data there, so we simply reuse
      64  			// the outbuf and overwrite the old data.
      65  			strm.next_out = outbuf;
      66  			strm.avail_out = sizeof(outbuf);
      67  		}
      68  	}
      69  
      70  	// LZMA_PROG_ERROR should never happen as long as the code calling
      71  	// the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign
      72  	// of a bug in either this function or in liblzma.
      73  	if (ret == LZMA_PROG_ERROR) {
      74  		fprintf(stderr, "lzma_code() returned LZMA_PROG_ERROR\n");
      75  		abort();
      76  	}
      77  
      78  	// Free the allocated memory.
      79  	lzma_end(&strm);
      80  
      81  	return 0;
      82  }