Makefile.am (5612B)
1 # This Makefile.am is in the public domain 2 3 # In-process fuzzing harnesses. See README in this directory. 4 # 5 # The harnesses are built only with --enable-fuzzing (see 6 # BUILD-INTEGRATION.md). They are ordinary check_PROGRAMS with a 7 # built-in deterministic driver, so they need neither clang nor 8 # libFuzzer nor AFL++; with those available the very same sources can be 9 # compiled into libFuzzer/AFL++ targets (again, see the README). 10 11 SUBDIRS = . 12 13 # Number of generate/mutate iterations per harness during "make check". 14 # Raise for a real fuzzing session, e.g. 15 # make MHD_FUZZ_ITERATIONS=1000000 MHD_FUZZ_SEED=42 check 16 # The whole suite takes about three seconds under ASAN+UBSAN at this value. 17 MHD_FUZZ_ITERATIONS = 50000 18 19 # PRNG seed; every run is exactly reproducible from (harness, seed). 20 MHD_FUZZ_SEED = 1 21 22 # Lower bound for MHD_OPTION_CLIENT_DISCIPLINE_LVL in fuzz_request. 23 # -3 is the full range: it includes the deliberately non-conformant 24 # parsing modes, which is where the most interesting inputs live. 25 MHD_FUZZ_MIN_DISCIPLINE = -3 26 27 # Lower bound for MHD_OPTION_CONNECTION_MEMORY_LIMIT in fuzz_request. 28 # 0 is the full range, including the tiny pools needed to reach the 29 # read-buffer "shift back" code path. 30 MHD_FUZZ_MIN_MEM_LIMIT = 0 31 32 # Where reproducers for failing inputs are written. 33 MHD_FUZZ_CRASH_DIR = crashes 34 35 AM_CPPFLAGS = \ 36 -I$(top_srcdir)/src/include \ 37 -I$(top_srcdir)/src/microhttpd \ 38 $(CPPFLAGS_ac) 39 40 AM_CFLAGS = $(CFLAGS_ac) 41 42 AM_LDFLAGS = $(LDFLAGS_ac) 43 44 AM_TESTS_ENVIRONMENT = $(TESTS_ENVIRONMENT_ac) \ 45 MHD_FUZZ_ITERATIONS="$(MHD_FUZZ_ITERATIONS)" ; \ 46 export MHD_FUZZ_ITERATIONS ; \ 47 MHD_FUZZ_SEED="$(MHD_FUZZ_SEED)" ; export MHD_FUZZ_SEED ; \ 48 MHD_FUZZ_MIN_DISCIPLINE="$(MHD_FUZZ_MIN_DISCIPLINE)" ; \ 49 export MHD_FUZZ_MIN_DISCIPLINE ; \ 50 MHD_FUZZ_MIN_MEM_LIMIT="$(MHD_FUZZ_MIN_MEM_LIMIT)" ; \ 51 export MHD_FUZZ_MIN_MEM_LIMIT ; \ 52 MHD_FUZZ_CRASH_DIR="$(MHD_FUZZ_CRASH_DIR)" ; \ 53 export MHD_FUZZ_CRASH_DIR ; 54 55 if USE_COVERAGE 56 AM_CFLAGS += -fprofile-arcs -ftest-coverage 57 endif 58 59 # fuzz_str and fuzz_auth_header call functions that are internal to the 60 # library (mhd_str.c, gen_auth.c, memorypool.c) and therefore hidden in 61 # the shared object; link them against the static archive. This 62 # requires a build with --enable-static (the default). 63 LDADD = \ 64 $(top_builddir)/src/microhttpd/libmicrohttpd.la 65 66 $(top_builddir)/src/microhttpd/libmicrohttpd.la: $(top_builddir)/src/microhttpd/Makefile 67 @echo ' cd $(top_builddir)/src/microhttpd && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.la'; \ 68 $(am__cd) $(top_builddir)/src/microhttpd && $(MAKE) $(AM_MAKEFLAGS) libmicrohttpd.la 69 70 check_PROGRAMS = \ 71 fuzz_request \ 72 fuzz_options \ 73 fuzz_eventloop \ 74 fuzz_str \ 75 fuzz_memorypool \ 76 fuzz_postprocessor 77 78 if HAVE_ANYAUTH 79 check_PROGRAMS += \ 80 fuzz_auth_header 81 endif 82 83 # fuzz_tls needs a TLS backend, and it links GnuTLS directly of its own 84 # accord: it drives a real client through the handshake rather than 85 # feeding bytes at MHD, which is what makes MHD's own TLS plumbing -- 86 # rather than GnuTLS's record parser -- the thing under test. 87 if ENABLE_HTTPS 88 check_PROGRAMS += \ 89 fuzz_tls 90 endif 91 92 .NOTPARALLEL: 93 94 TESTS = $(check_PROGRAMS) 95 96 fuzz_request_SOURCES = \ 97 fuzz_request.c fuzz_common.h 98 fuzz_request_LDFLAGS = $(AM_LDFLAGS) -static 99 100 fuzz_options_SOURCES = \ 101 fuzz_options.c fuzz_common.h 102 fuzz_options_LDFLAGS = $(AM_LDFLAGS) -static 103 104 fuzz_eventloop_SOURCES = \ 105 fuzz_eventloop.c fuzz_common.h 106 fuzz_eventloop_LDFLAGS = $(AM_LDFLAGS) -static 107 108 fuzz_tls_SOURCES = \ 109 fuzz_tls.c fuzz_common.h 110 fuzz_tls_CPPFLAGS = $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) 111 fuzz_tls_LDFLAGS = $(AM_LDFLAGS) $(MHD_TLS_LIB_LDFLAGS) -static 112 fuzz_tls_LDADD = $(LDADD) $(MHD_TLS_LIBDEPS) 113 114 fuzz_str_SOURCES = \ 115 fuzz_str.c fuzz_common.h 116 fuzz_str_LDFLAGS = $(AM_LDFLAGS) -static 117 118 fuzz_auth_header_SOURCES = \ 119 fuzz_auth_header.c fuzz_common.h 120 fuzz_auth_header_LDFLAGS = $(AM_LDFLAGS) -static 121 122 fuzz_memorypool_SOURCES = \ 123 fuzz_memorypool.c fuzz_common.h 124 fuzz_memorypool_LDFLAGS = $(AM_LDFLAGS) -static 125 126 fuzz_postprocessor_SOURCES = \ 127 fuzz_postprocessor.c fuzz_common.h 128 fuzz_postprocessor_LDFLAGS = $(AM_LDFLAGS) -static 129 130 # The whole corpus directory is distributed as-is. 131 EXTRA_DIST = \ 132 README \ 133 BUILD-INTEGRATION.md \ 134 corpus 135 136 CLEANFILES = \ 137 $(MHD_FUZZ_CRASH_DIR)/*.bin 138 139 # Regenerate the on-disk seed corpus from the built-in one. 140 .PHONY: refresh-corpus 141 refresh-corpus: $(check_PROGRAMS) 142 for p in $(check_PROGRAMS) ; do \ 143 ./$$p --write-corpus=$(srcdir)/corpus || exit 1 ; \ 144 done 145 146 # Replay the whole on-disk corpus through every harness; this is what a 147 # CI regression run should do after a crash has been fixed. 148 # 149 # corpus/known-findings/ is listed separately because --corpus-dir does 150 # not recurse. It holds the reproducers of the findings in README 151 # section 6; all of them are fixed, so anything failing there is a 152 # regression. The one intended exception is a reproducer committed while 153 # its finding is still open: that fails here until the fix lands, which 154 # is what a regression test for an unfixed bug is supposed to do. 155 # 156 # Note that these only bite on a tree configured with --enable-asserts; 157 # without it mhd_assert() compiles away and most of these reproducers 158 # pass whether MHD is fixed or not. 159 CORPUS_DIRS = \ 160 $(srcdir)/corpus \ 161 $(srcdir)/corpus/known-findings 162 163 .PHONY: check-corpus 164 check-corpus: $(check_PROGRAMS) 165 for p in $(check_PROGRAMS) ; do \ 166 for d in $(CORPUS_DIRS) ; do \ 167 MHD_FUZZ_MIN_DISCIPLINE="$(MHD_FUZZ_MIN_DISCIPLINE)" \ 168 MHD_FUZZ_MIN_MEM_LIMIT="$(MHD_FUZZ_MIN_MEM_LIMIT)" \ 169 ./$$p --corpus-dir=$$d || exit 1 ; \ 170 done ; \ 171 done