|
GNU libmicrohttpd 1.0.9
|
Shared, header-only fuzzing driver for the MHD in-process fuzzers. More...
#include <stdint.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include <dirent.h>

Go to the source code of this file.
Data Structures | |
| struct | fuzz_rng |
Macros | |
| #define | FUZZ_HARNESS_NAME "fuzz" |
| #define | FUZZ_UNUSED __attribute__ ((unused)) |
| #define | FUZZ_MAX_INPUT 32768 |
| #define | FUZZ_DEFAULT_ITERATIONS 3000 |
| #define | FUZZ_DEFAULT_TIMEOUT 20 |
Functions | |
| int | LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) |
| static FUZZ_UNUSED size_t | fuzz_generate (struct fuzz_rng *rng, uint8_t *buf, size_t cap) |
| static FUZZ_UNUSED size_t | fuzz_seed_count (void) |
| static FUZZ_UNUSED const uint8_t * | fuzz_seed_get (size_t idx, size_t *len) |
| static FUZZ_UNUSED uint64_t | fuzz_splitmix64 (uint64_t *x) |
| static FUZZ_UNUSED void | fuzz_rng_seed (struct fuzz_rng *r, uint64_t seed) |
| static FUZZ_UNUSED uint64_t | fuzz_rot64 (uint64_t x, unsigned int k) |
| static FUZZ_UNUSED uint64_t | fuzz_next (struct fuzz_rng *r) |
| static FUZZ_UNUSED uint32_t | fuzz_below (struct fuzz_rng *r, uint32_t n) |
| static FUZZ_UNUSED uint8_t | fuzz_byte (struct fuzz_rng *r) |
| static FUZZ_UNUSED int | fuzz_chance (struct fuzz_rng *r, uint32_t n) |
| static FUZZ_UNUSED void | fuzz_write_all (int fd, const void *buf, size_t len) |
| static FUZZ_UNUSED void | fuzz_msg (const char *s) |
| static FUZZ_UNUSED void | fuzz_dump_current (void) |
| static FUZZ_UNUSED void | fuzz_death_callback (void) |
| static FUZZ_UNUSED void | fuzz_sig_handler (int sig) |
| static FUZZ_UNUSED void | fuzz_report_finding (const char *what) |
| void | __sanitizer_set_death_callback (void(*cb)(void)) __attribute__((weak)) |
| static FUZZ_UNUSED void | fuzz_ignore_sigpipe (void) |
| static void | fuzz_install_handlers (void) |
| static void | fuzz_set_current (const uint8_t *data, size_t size, const char *tag) |
| static size_t | fuzz_mutate_once (struct fuzz_rng *rng, uint8_t *buf, size_t len, size_t cap) |
| static int | fuzz_run_file (const char *path) |
| static int | fuzz_run_corpus_dir (const char *dir) |
| static void | fuzz_usage (const char *argv0) |
| static int | fuzz_write_corpus (const char *dir) |
| int | main (int argc, char *const *argv) |
Variables | |
| static FUZZ_UNUSED int | fuzz_pristine |
| static FUZZ_UNUSED int | fuzz_verbose |
| static FUZZ_UNUSED int | fuzz_skip_seeds |
| static FUZZ_UNUSED uint64_t | fuzz_cur_seed |
| static FUZZ_UNUSED uint64_t | fuzz_cur_iter |
| static const uint8_t * | fuzz_cur_input |
| static size_t | fuzz_cur_input_len |
| static const char * | fuzz_crash_dir = "crashes" |
| static char | fuzz_crash_path [512] |
| static char | fuzz_crash_msg [512] |
| static volatile sig_atomic_t | fuzz_dumped |
| static const uint8_t | fuzz_interesting [] |
| static const char *const | fuzz_interesting_str [] |
Shared, header-only fuzzing driver for the MHD in-process fuzzers.
Every harness in this directory is a single translation unit that includes this header. The header provides:
main() driver (generator + mutator loop, corpus replay, single-file replay) so that the harnesses are usable with a plain gcc + ASAN/UBSAN build, i.e. without clang/libFuzzer.The harness itself must provide:
LLVMFuzzerTestOneInput() (the actual fuzz target),fuzz_generate() (a structure-aware input generator),fuzz_seed_count() / fuzz_seed_get() (a built-in seed corpus).Define FUZZ_NO_MAIN when linking against libFuzzer or AFL++'s driver, which supply their own main().
Definition in file fuzz_common.h.
| #define FUZZ_DEFAULT_ITERATIONS 3000 |
Default number of iterations of the built-in driver. Kept small so that "make check" stays in the "couple of seconds" range; raise with –iterations=N or the MHD_FUZZ_ITERATIONS environment variable.
Definition at line 82 of file fuzz_common.h.
Referenced by fuzz_usage(), and main().
| #define FUZZ_DEFAULT_TIMEOUT 20 |
Default per-iteration watchdog, in seconds.
Definition at line 89 of file fuzz_common.h.
Referenced by fuzz_run_file(), fuzz_usage(), and main().
| #define FUZZ_HARNESS_NAME "fuzz" |
Definition at line 61 of file fuzz_common.h.
Referenced by fuzz_run_corpus_dir(), fuzz_run_file(), fuzz_set_current(), fuzz_usage(), fuzz_write_corpus(), and main().
| #define FUZZ_MAX_INPUT 32768 |
Hard upper bound on the size of a single fuzz input.
Definition at line 73 of file fuzz_common.h.
Referenced by fuzz_run_file(), LLVMFuzzerTestOneInput(), and main().
| #define FUZZ_UNUSED __attribute__ ((unused)) |
Not every harness uses every helper; silence -Wunused-function.
Definition at line 67 of file fuzz_common.h.
|
extern |
|
static |
Definition at line 200 of file fuzz_common.h.
References fuzz_next().
Referenced by emit_segments(), emit_segments(), fuzz_chance(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_mutate_once(), gen_chunked_body(), gen_digest_header(), gen_frag(), gen_headers(), gen_loop_round(), gen_one_request(), gen_query(), gen_request(), gen_size_sel(), and main().


|
static |
Definition at line 210 of file fuzz_common.h.
References fuzz_next().
Referenced by fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_mutate_once(), and gen_request().


|
static |
Definition at line 220 of file fuzz_common.h.
References fuzz_below().
Referenced by emit_segments(), emit_segments(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), fuzz_generate(), gen_chunked_body(), gen_digest_header(), gen_frag(), gen_headers(), gen_loop_round(), gen_one_request(), and gen_query().


|
static |
Definition at line 329 of file fuzz_common.h.
References fuzz_dump_current().
Referenced by fuzz_install_handlers().


|
static |
Dump the input of the currently running iteration so that the failure can be replayed with –file=... Async-signal-safe.
Definition at line 299 of file fuzz_common.h.
References fd, fuzz_crash_dir, fuzz_crash_msg, fuzz_crash_path, fuzz_cur_input, fuzz_cur_input_len, fuzz_dumped, fuzz_msg(), fuzz_write_all(), and NULL.
Referenced by fuzz_death_callback(), fuzz_report_finding(), and fuzz_sig_handler().


|
static |
Structure-aware generator used by the built-in standalone driver. Must write at most cap bytes to buf and return the number of bytes written. Purely random bytes almost never form a valid HTTP request, so this is what actually makes the gcc-only driver useful.
Referenced by main().

|
static |
Ignore SIGPIPE. Idempotent, so it is safe to call on every execution.
This deliberately lives OUTSIDE the #ifndef FUZZ_NO_MAIN block below, because it is needed by the fuzz target, not merely by the built-in driver. fuzz_request writes into an AF_UNIX socketpair whose peer end MHD may already have closed (any input that makes the daemon drop the connection early does this), and a write() to a socket with no reader raises SIGPIPE.
None of the external engines does this for us: libFuzzer intercepts SEGV/BUS/ABRT/ILL/FPE/INT/TERM/XFSZ/USR1/USR2 and has no -handle_sigpipe flag at all, and AFL++/honggfuzz likewise leave the default disposition in place. So without this call an OSS-Fuzz build of fuzz_request is killed by SIGPIPE after a few dozen executions, with no stack trace, no artifact and no report – the target simply stops fuzzing. Measured here: dead after ~28 execs without it, 540000 execs in 31 s with it.
Definition at line 399 of file fuzz_common.h.
Referenced by fuzz_install_handlers(), and LLVMFuzzerTestOneInput().

|
static |
Definition at line 413 of file fuzz_common.h.
References __sanitizer_set_death_callback(), fuzz_death_callback(), fuzz_ignore_sigpipe(), fuzz_sig_handler(), and NULL.
Referenced by main().


|
static |
Definition at line 288 of file fuzz_common.h.
References fuzz_write_all().
Referenced by fuzz_dump_current(), fuzz_report_finding(), and fuzz_sig_handler().


|
static |
Apply a single random mutation to buf.
| rng | the PRNG state | |
| [in,out] | buf | the buffer to mutate |
| len | current length | |
| cap | capacity of buf |
Definition at line 491 of file fuzz_common.h.
References fuzz_below(), fuzz_byte(), fuzz_interesting, and fuzz_interesting_str.
Referenced by main().


|
static |
xoshiro256** – small, fast, deterministic and identical on every platform, which is what we need for reproducible fuzzing runs.
Definition at line 181 of file fuzz_common.h.
References fuzz_rot64(), and fuzz_rng::s.
Referenced by fuzz_below(), and fuzz_byte().


|
static |
Report a logical (non-memory-safety) finding: dump the reproducer and abort so that the failure is impossible to overlook.
Definition at line 356 of file fuzz_common.h.
References fuzz_crash_msg, fuzz_dump_current(), and fuzz_msg().
Referenced by ahc(), check_fdsets(), check_timeouts(), fz_report(), LLVMFuzzerTestOneInput(), op_fdset(), op_quiesce(), oracle_check_body(), panic_cb(), panic_cb(), panic_cb(), and post_iter().


|
static |
Definition at line 157 of file fuzz_common.h.
References fuzz_splitmix64(), and fuzz_rng::s.
Referenced by main().


|
static |
Definition at line 169 of file fuzz_common.h.
Referenced by fuzz_next().

|
static |
Definition at line 635 of file fuzz_common.h.
References fuzz_cur_iter, FUZZ_HARNESS_NAME, fuzz_run_file(), and NULL.
Referenced by main().


|
static |
Definition at line 600 of file fuzz_common.h.
References FUZZ_DEFAULT_TIMEOUT, FUZZ_HARNESS_NAME, FUZZ_MAX_INPUT, fuzz_pristine, fuzz_set_current(), LLVMFuzzerTestOneInput(), and NULL.
Referenced by fuzz_run_corpus_dir(), and main().


|
static |
Referenced by fuzz_write_corpus(), and main().

|
static |
| idx | index of the seed to retrieve | |
| [out] | len | set to the length of the seed |
Referenced by fuzz_write_corpus(), and main().

|
static |
Remember which input we are about to feed to the target, and pre-render the name of the file it would be dumped to.
Definition at line 438 of file fuzz_common.h.
References data, fuzz_crash_dir, fuzz_crash_msg, fuzz_crash_path, fuzz_cur_input, fuzz_cur_input_len, fuzz_cur_iter, fuzz_cur_seed, fuzz_dumped, and FUZZ_HARNESS_NAME.
Referenced by fuzz_run_file(), and main().

|
static |
Definition at line 336 of file fuzz_common.h.
References fuzz_dump_current(), and fuzz_msg().
Referenced by fuzz_install_handlers().


|
static |
Definition at line 144 of file fuzz_common.h.
Referenced by fuzz_rng_seed().

|
static |
Definition at line 674 of file fuzz_common.h.
References FUZZ_DEFAULT_ITERATIONS, FUZZ_DEFAULT_TIMEOUT, and FUZZ_HARNESS_NAME.
Referenced by main().

|
static |
Definition at line 270 of file fuzz_common.h.
References fd.
Referenced by fuzz_dump_current(), and fuzz_msg().

|
static |
Definition at line 702 of file fuzz_common.h.
References FUZZ_HARNESS_NAME, fuzz_seed_count(), fuzz_seed_get(), and NULL.
Referenced by main().


| int LLVMFuzzerTestOneInput | ( | const uint8_t * | data, |
| size_t | size ) |
The fuzz target. Signature is the libFuzzer one on purpose, so that the very same harness can be linked with libFuzzer or AFL++ later.
< see queue_unprocessed_conn()
Definition at line 201 of file fuzz_auth_header.c.
References ahc(), ahc(), algo_tbl, big_body, BIG_BODY_LEN, big_body_ready, build_options(), cfg, cfg, cfg, CFG_BYTES, check_timeouts(), chunk_patterns, clk_ms, close_conn(), close_connection(), close_connection(), completed_cb(), connect_real(), csock, cur_conn, cur_daemon, cur_daemon, MHD_Connection::daemon, data, DAUTH_VARIANT_COUNT, deadline_ms, deadline_valid, digest_rnd, discipline_tbl, do_resume(), do_suspend(), drain_all(), drain_conn(), dup_z(), expand_nonce(), expect_body, expect_body_len, expiry_budget, expiry_budget_read, flags_from_input(), frag_tbl, full_dealloc_enabled, fuzz_dup_n(), fuzz_ignore_sigpipe(), FUZZ_MAX_INPUT, fuzz_pristine, fuzz_report_finding(), fuzz_verbose, fz_do_op(), FZ_MAX_OPS, fz_pool_close(), fz_pool_open(), fz_verify_all(), g_have_sets, g_max_fd, g_setsize, get_shared_daemon(), get_shared_daemon(), MHD_HTTP_Req_Header::header, MHD_HTTP_Req_Header::header_size, MHD_Request::headers_received, MHD_Request::headers_received_tail, MHD_HTTP_Req_Header::kind, known_bugs_read, _MHD_str_w_len::len, lives, MAX_CONNECTIONS, MAX_CONNS, MAX_EXPECT_BODY, MAX_LIVE, MAX_OPS, MAX_OPTS, MAX_SEGMENTS, mem_limit_tbl, mem_limit_tbl, MHD_ALLOW_SUSPEND_RESUME, MHD_ALLOW_UPGRADE, MHD_bin_to_hex(), MHD_bin_to_hex_z(), MHD_CONNECTION_HEADERS_PROCESSED, MHD_create_post_processor(), MHD_destroy_post_processor(), MHD_DIGEST_AUTH_ALGO3_MD5, MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, MHD_DIGEST_AUTH_ALGO3_SHA256, MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, MHD_DIGEST_AUTH_ALGO3_SHA512_256, MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION, MHD_digest_auth_calc_userdigest(), MHD_digest_auth_calc_userhash(), MHD_digest_auth_calc_userhash_hex(), MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT, MHD_DIGEST_AUTH_MULT_QOP_AUTH, MHD_digest_get_hash_size(), MHD_DSC_SANE, MHD_FEATURE_UPGRADE, MHD_HEADER_KIND, MHD_hex_to_bin(), MHD_HTTP_HEADER_AUTHORIZATION, MHD_HTTP_HEADER_CONTENT_TYPE, MHD_HTTP_POST_ENCODING_FORM_URLENCODED, MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, MHD_init_mem_pools_(), MHD_INVALID_SOCKET, MHD_is_feature_supported(), MHD_OPTION_APP_FD_SETSIZE, MHD_OPTION_ARRAY, MHD_OPTION_CLIENT_DISCIPLINE_LVL, MHD_OPTION_CONNECTION_LIMIT, MHD_OPTION_CONNECTION_MEMORY_LIMIT, MHD_OPTION_CONNECTION_TIMEOUT, MHD_OPTION_DIGEST_AUTH_RANDOM, MHD_OPTION_END, MHD_OPTION_NONCE_NC_SIZE, MHD_OPTION_NOTIFY_COMPLETED, MHD_OPTION_NOTIFY_CONNECTION, MHD_OPTION_SERVER_INSANITY, MHD_pool_create(), MHD_pool_destroy(), MHD_post_process(), MHD_quiesce_daemon(), MHD_run(), MHD_set_panic_func(), MHD_start_daemon(), MHD_STATICSTR_LEN_, MHD_stop_daemon(), MHD_str_equal_caseless_bin_n_(), MHD_str_equal_caseless_n_(), MHD_str_has_token_caseless_(), MHD_str_pct_decode_in_place_lenient_(), MHD_str_pct_decode_in_place_strict_(), MHD_str_pct_decode_lenient_n_(), MHD_str_pct_decode_strict_n_(), MHD_str_remove_token_caseless_(), MHD_str_remove_tokens_caseless_(), MHD_str_to_uint64_n_(), MHD_strx_to_uint64_n_(), MHD_USE_ERROR_LOG, MHD_USE_INTERNAL_POLLING_THREAD, MHD_USE_ITC, MHD_USE_NO_LISTEN_SOCKET, MHD_USE_NO_THREAD_SAFETY, MHD_USE_THREAD_PER_CONNECTION, MHD_YES, min_discipline, min_discipline_read, min_mem_limit, min_mem_limit_read, model_digest_sink, model_digest_sink_read, MODEL_MAX_DIGEST, nconns, new_connection(), new_connection(), new_connection(), nnc_tbl, nonce_len, nonce_val, notify_conn_cb(), NULL, OP_CLOCK, OP_CLOSECONN, OP_CONNOPT, op_connopt(), OP_DRAIN, OP_FDSET, op_fdset(), OP_INFO, op_info(), OP_NEWCONN, op_poll(), OP_QUIESCE, op_quiesce(), OP_RESUME, OP_RUN, op_run(), OP_SEND_FRAG, OP_SEND_RAW, OP_SUSPEND, OP_SWITCH, OP_TIMEOUT, MHD_OptionItem::option, oracle_on, panic_cb(), panic_cb(), panic_cb(), pending_resume, pending_resume, pending_resume_flush(), pending_resume_flush(), MHD_Connection::pool, pool_sizes, post_iter(), pp_buf_sizes, print_stats(), print_stats(), print_stats(), print_stats(), MHD_OptionItem::ptr_value, pump(), pump(), PUMP_ROUNDS, PUMP_ROUNDS_LONG, query_daemon_info(), query_feature(), queue_unprocessed_conn(), quiesce_epoll_race_allowed(), quiesced_fd, resp_buf, resp_len, resume_all(), MHD_Connection::rq, send_all(), send_all(), send_bytes(), shared_daemon, shared_daemon, start_daemon_variant(), stat_bauth_failed, stat_bauth_parsed, stat_daemons, stat_daemons, stat_daemons, stat_daemons_failed, stat_dauth_failed, stat_dauth_parsed, stat_pp_created, stat_pp_failed, stat_threaded, MHD_Connection::state, stats_registered, stats_registered, stats_registered, _MHD_str_w_len::str, SUSPEND_BIT, tearing_down, tearing_down, tearing_down, TGT_BASE64, TGT_BIN_TO_HEX, TGT_BIN_TO_HEX_Z, TGT_COUNT, TGT_DIGEST_HEX_SINK, TGT_EQUAL_CASELESS, TGT_HEX_TO_BIN, TGT_PCT_IN_PLACE_LENIENT, TGT_PCT_IN_PLACE_STRICT, TGT_PCT_LENIENT, TGT_PCT_STRICT, TGT_QUOTE, TGT_TO_UINT64, TGT_TOKENS, TGT_UNQUOTE, timeout_tbl, MHD_RqBAuth::token68, uses_epoll(), MHD_HTTP_Req_Header::value, MHD_OptionItem::value, MHD_HTTP_Req_Header::value_size, wait_for_expiry(), wait_threaded(), wrap_realloc_enabled, and xalloc().
Referenced by fuzz_run_file(), and main().

| int main | ( | int | argc, |
| char *const * | argv ) |
Definition at line 744 of file fuzz_common.h.
References fuzz_below(), fuzz_crash_dir, fuzz_cur_iter, fuzz_cur_seed, FUZZ_DEFAULT_ITERATIONS, FUZZ_DEFAULT_TIMEOUT, fuzz_generate(), FUZZ_HARNESS_NAME, fuzz_install_handlers(), FUZZ_MAX_INPUT, fuzz_mutate_once(), fuzz_pristine, fuzz_rng_seed(), fuzz_run_corpus_dir(), fuzz_run_file(), fuzz_seed_count(), fuzz_seed_get(), fuzz_set_current(), fuzz_skip_seeds, fuzz_usage(), fuzz_verbose, fuzz_write_corpus(), LLVMFuzzerTestOneInput(), NULL, and fuzz_rng::s.

|
static |
Definition at line 260 of file fuzz_common.h.
Referenced by fuzz_dump_current(), fuzz_set_current(), and main().
|
static |
Definition at line 265 of file fuzz_common.h.
Referenced by fuzz_dump_current(), fuzz_report_finding(), and fuzz_set_current().
|
static |
Definition at line 264 of file fuzz_common.h.
Referenced by fuzz_dump_current(), and fuzz_set_current().
|
static |
Definition at line 258 of file fuzz_common.h.
Referenced by fuzz_dump_current(), and fuzz_set_current().
|
static |
Definition at line 259 of file fuzz_common.h.
Referenced by fuzz_dump_current(), and fuzz_set_current().
|
static |
Definition at line 257 of file fuzz_common.h.
Referenced by fuzz_run_corpus_dir(), fuzz_set_current(), and main().
|
static |
Definition at line 256 of file fuzz_common.h.
Referenced by fuzz_set_current(), and main().
|
static |
Definition at line 266 of file fuzz_common.h.
Referenced by fuzz_dump_current(), and fuzz_set_current().
|
static |
Definition at line 466 of file fuzz_common.h.
Referenced by fuzz_mutate_once().
|
static |
Definition at line 472 of file fuzz_common.h.
Referenced by fuzz_mutate_once().
|
static |
Non-zero if the input of the current iteration comes from a trusted source (the built-in generator, the built-in seed corpus, –file or –corpus-dir) and has NOT been mutated afterwards. Harnesses use this to enable "ground truth" oracles, e.g. the expected decoded request body that a generated chunked request declares. Random mutations invalidate such declarations, hence the flag.
Definition at line 239 of file fuzz_common.h.
Referenced by fuzz_run_file(), LLVMFuzzerTestOneInput(), and main().
|
static |
Non-zero to skip the replay of the built-in seed corpus at the start of a run (useful when a seed is known to trigger an already-reported finding and one wants to look for others).
Definition at line 251 of file fuzz_common.h.
Referenced by main().
|
static |
Non-zero to let the harness enable MHD's own error log.
Definition at line 244 of file fuzz_common.h.
Referenced by get_shared_daemon(), get_shared_daemon(), LLVMFuzzerTestOneInput(), logger_cb(), main(), print_stats(), print_stats(), print_stats(), print_stats(), print_stats(), and print_stats().