Line data Source code
1 : #include "fd_fuzz.h"
2 : #include "../fd_util.h"
3 :
4 : #include <errno.h>
5 : #include <fcntl.h>
6 : #include <stdlib.h>
7 : #include <stdio.h>
8 : #include <sys/stat.h>
9 : #include <unistd.h>
10 :
11 : /* fd_fuzz_stub.c is a stub fuzz harness for build targets without an
12 : actual fuzz engine. This harness mocks the libFuzzer command-line
13 : and can regression test against existing input files. It cannot,
14 : however, do any actual fuzz exploration. */
15 :
16 : static int
17 0 : i_am_a_stub( void ) {
18 0 : fputs( "FAIL: No fuzz engine.\n"
19 0 : "\n"
20 0 : "This fuzz target was compiled without a fuzz engine.\n"
21 0 : "You can still re-run individual test cases like so:\n"
22 0 : " <prog> path/to/file1 path/to/file2 ...\n"
23 0 : "\n"
24 0 : "Hint: Compile with CC=clang EXTRAS=fuzz to build with the libFuzzer engine.\n",
25 0 : stderr );
26 0 : return 1;
27 0 : }
28 :
29 : extern int
30 : LLVMFuzzerInitialize( int * argc,
31 : char *** argv );
32 :
33 : extern int
34 : LLVMFuzzerTestOneInput( uchar const * data,
35 : ulong data_sz );
36 :
37 : __attribute__((weak))
38 : ulong
39 : LLVMFuzzerMutate( uchar * data,
40 : ulong data_sz,
41 0 : ulong max_sz ) {
42 0 : (void)data; (void)data_sz; (void)max_sz;
43 0 : return 0UL;
44 0 : }
45 :
46 : int
47 : main( int argc,
48 21 : char ** argv ) {
49 : /* fd_boot is typically called by the target, so we don't call it here. */
50 :
51 21 : if( argc<=1 ) return i_am_a_stub();
52 :
53 21 : LLVMFuzzerInitialize( &argc, &argv );
54 :
55 3456 : for( int i=1; i<argc; i++ ) {
56 3435 : if( argv[i][0] == '-' ) continue;
57 :
58 3372 : fprintf( stderr, "Running: %s\n", argv[i] );
59 :
60 3372 : int file = open( argv[i], O_RDONLY );
61 3372 : if( FD_UNLIKELY( file<0 ) ) {
62 0 : FD_LOG_ERR(( "open(%s) failed (%d-%s)", argv[i], errno, fd_io_strerror( errno ) ));
63 0 : return 1;
64 0 : }
65 :
66 3372 : struct stat st;
67 3372 : if( FD_UNLIKELY( 0!=fstat( file, &st ) ) ) {
68 0 : FD_LOG_ERR(( "fstat(%d) failed (%d-%s)", file, errno, fd_io_strerror( errno ) ));
69 0 : return 1;
70 0 : }
71 :
72 3372 : if( st.st_mode == S_IFDIR )
73 0 : return i_am_a_stub();
74 3372 : ulong file_sz = (ulong)st.st_size;
75 :
76 3372 : uchar * buf = malloc( file_sz );
77 3372 : if( !buf )
78 0 : FD_LOG_ERR(( "FAIL: Out of memory (failed to malloc %lu bytes)", file_sz ));
79 :
80 3372 : ulong actual_read_sz;
81 3372 : int read_err = fd_io_read( file, buf, file_sz, file_sz, &actual_read_sz );
82 3372 : close( file );
83 3372 : if( FD_UNLIKELY( read_err ) ) {
84 0 : free( buf );
85 0 : FD_LOG_ERR(( "fd_io_read(%d,%lu) failed (%d-%s)", file, file_sz, errno, fd_io_strerror( errno ) ));
86 0 : return 1;
87 0 : }
88 :
89 3372 : LLVMFuzzerTestOneInput( buf, actual_read_sz );
90 3372 : fprintf( stderr, "Executed %s\n", argv[i] );
91 :
92 3372 : free( buf );
93 3372 : }
94 :
95 21 : return 0;
96 21 : }
|