libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

fuzz_options.c (76421B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2026 Christian Grothoff
      4 
      5   This library is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU Lesser General Public
      7   License as published by the Free Software Foundation; either
      8   version 2.1 of the License, or (at your option) any later version.
      9 
     10   This library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library.
     17   If not, see <http://www.gnu.org/licenses/>.
     18 */
     19 
     20 /**
     21  * @file fuzz/fuzz_options.c
     22  * @brief In-process fuzzer for MHD's daemon option handling and for the
     23  *        daemon start-up / shutdown paths.
     24  * @author Christian Grothoff
     25  *
     26  * fuzz_request.c fuzzes what MHD does with the *bytes on the wire*, but
     27  * it always starts the daemon in one single shape: external polling, no
     28  * listen socket, five fixed options.  Everything in daemon.c that is
     29  * reached through any other configuration -- the flag validation in
     30  * MHD_start_daemon(), parse_options_va(), the internal polling thread,
     31  * the thread pool, epoll/poll/select, the listen socket, the per-IP and
     32  * per-daemon connection limits, quiesce -- is therefore dead code as far
     33  * as the fuzzing suite is concerned.  This harness closes that gap: the
     34  * input bytes pick a *combination* of MHD_FLAG bits and an MHD_OPTION
     35  * array, the daemon is started with them, one short HTTP request is
     36  * driven through it over a socketpair, and the daemon is stopped again.
     37  *
     38  * The request-driving machinery is the one from fuzz_request.c:
     39  * MHD_USE_NO_LISTEN_SOCKET plus MHD_add_connection() on an AF_UNIX
     40  * socketpair(), with a fake 127.0.0.1 peer address so that the per-IP
     41  * accounting sees something sane, and MHD_set_panic_func() installed as
     42  * a tripwire.  What is new here is that the *daemon* is a variable.
     43  *
     44  * Two shapes of daemon exist, and the harness drives them differently:
     45  *
     46  *   - "external polling" (no MHD_USE_INTERNAL_POLLING_THREAD and no
     47  *     MHD_USE_THREAD_PER_CONNECTION).  Single threaded and fully
     48  *     deterministic: the segments are fed in one at a time and the
     49  *     daemon is pumped with MHD_run() / MHD_get_fdset2() + select() +
     50  *     MHD_run_from_select2() / MHD_run_wait() between them.  This is the
     51  *     majority of the iterations and the only shape in which the harness
     52  *     suspends a connection.
     53  *
     54  *   - "internal thread" (an internal polling thread, a thread pool, or
     55  *     thread-per-connection).  MHD_add_connection() is explicitly
     56  *     supported in these modes -- it is how an application with its own
     57  *     accept() loop hands sockets over -- but the harness must not also
     58  *     poll the daemon, and it cannot know when the worker is done.  So
     59  *     the whole request is written at once, the write side is shut down
     60  *     (which makes MHD finish the request immediately rather than
     61  *     waiting for more data), and the answer is awaited with a short
     62  *     bounded poll() before the daemon is stopped.  MHD_USE_ITC is
     63  *     forced on in this shape so that the worker picks the new
     64  *     connection up at once instead of waiting for its poll timeout.
     65  *     No connection is ever suspended here.
     66  *
     67  * Input format (see README section 2.2 for the fuzz_request one, which
     68  * the segment stream below is deliberately identical to):
     69  *
     70  *   byte 0    daemon shape: index into mode_tbl[] (event loop and
     71  *             threading; the entries are the combinations MHD documents
     72  *             as valid, so that most iterations get a live daemon)
     73  *   byte 1    MHD_FLAG bits, group A (see flags_from_input())
     74  *   byte 2    MHD_FLAG bits, group B; 0xC0 in the top two bits switches
     75  *             on the "raw" escape, which feeds bytes 1, 2 and 15
     76  *             straight into the flags word.  That is what fuzzes
     77  *             MHD_start_daemon()'s own combination checks; MHD answering
     78  *             NULL is a normal outcome and simply ends the iteration.
     79  *   byte 3    option presence mask A (sizes and limits)
     80  *   byte 4    option presence mask B (discipline, insanity, fd_setsize)
     81  *   byte 5    option presence mask C (the callbacks and the pointers)
     82  *   byte 6    value selector: connection memory limit / increment
     83  *   byte 7    value selector: connection limit / per-IP limit
     84  *   byte 8    value selector: connection timeout / pool size / stack
     85  *   byte 9    value selector: nonce-nc size / digest random / bind type
     86  *   byte 10   value selector: discipline / strict / insanity / bzero URI
     87  *   byte 11   value selector: backlog / fd_setsize / reuse / fastopen
     88  *   byte 12   driver behaviour: event loop variant, quiesce,
     89  *             introspection, suspend mode, number of connections
     90  *   byte 13   handler behaviour (which response, MHD_NO, per-connection
     91  *             option) and the accept path: whether an accept policy
     92  *             callback is installed, what it answers, and whether the
     93  *             iteration additionally connect()s to the daemon's real
     94  *             listening socket
     95  *   byte 14   option presence mask D (the digest and TLS-adjacent
     96  *             options, MHD_OPTION_LISTEN_SOCKET, and the deliberately
     97  *             invalid option number)
     98  *   byte 15   spare entropy; also supplies flag bits 14+ in raw mode
     99  *   byte 16.  a sequence of send segments, each introduced by a little
    100  *             endian 16 bit header  (op << 14) | length
    101  *               op 0  send the payload on the current connection
    102  *               op 1  send the payload, then pump extra rounds
    103  *               op 2  send the payload, then pump extra rounds
    104  *               op 3  close the current connection, open a fresh one on
    105  *                     the same daemon, then send
    106  *
    107  * The sixteen configuration bytes are mandatory; a shorter input is
    108  * rejected.  An input of exactly sixteen bytes is meaningful and is not
    109  * a degenerate case: it starts and stops a daemon with one connection
    110  * and no traffic at all, which is precisely the start-up/shutdown path
    111  * this harness is about.
    112  *
    113  * Two rules the harness obeys, both of them application contract rather
    114  * than anything worth fuzzing:
    115  *
    116  *   - every daemon that starts is stopped, and no connection is left
    117  *     suspended when that happens, because MHD_stop_daemon() answers a
    118  *     suspended connection with MHD_PANIC().  Suspended connections are
    119  *     tracked in pending_resume[] and flushed during teardown, exactly
    120  *     as in fuzz_request.c;
    121  *   - the socket that MHD_quiesce_daemon() returns belongs to the
    122  *     caller.  It is closed after MHD_stop_daemon() (not before: with
    123  *     internal threads a worker may still be using it), otherwise the
    124  *     harness runs out of file descriptors within a few thousand
    125  *     iterations.
    126  *
    127  * Environment:
    128  *
    129  *   MHD_FUZZ_QUIESCE_EPOLL_RACE=1  let the harness call
    130  *       MHD_quiesce_daemon() on an epoll daemon that runs its own
    131  *       thread(s).  Off by default because that combination reaches an
    132  *       open MHD defect; see quiesce_epoll_race_allowed() below.
    133  */
    134 
    135 #define FUZZ_HARNESS_NAME "fuzz_options"
    136 #include "fuzz_common.h"
    137 
    138 #include <microhttpd.h>
    139 #include <sys/socket.h>
    140 #include <netinet/in.h>
    141 #include <sys/select.h>
    142 #include <poll.h>
    143 #include <limits.h>
    144 
    145 /* MHD_OPTION_STRICT_FOR_CLIENT is superseded by
    146    MHD_OPTION_CLIENT_DISCIPLINE_LVL but is still shipped API, and its
    147    mapping onto the discipline level is exactly the kind of thing this
    148    harness is for. */
    149 #if defined(__GNUC__) || defined(__clang__)
    150 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    151 #endif
    152 
    153 /** Number of mandatory configuration bytes at the start of the input. */
    154 #define CFG_BYTES 16
    155 
    156 #define MAX_SEGMENTS 48
    157 #define MAX_CONNECTIONS 6
    158 #define MAX_OPTS 40
    159 #define RESP_DRAIN_BUF 4096
    160 #define GEN_BUF_SIZE 4096
    161 
    162 /**
    163  * Milliseconds the internal-thread shape waits for the daemon to answer.
    164  * The write side of the socketpair is shut down before the wait, so the
    165  * daemon never sits on an incomplete request: either it answers (the
    166  * common case, tens of microseconds) or it closes the connection, and
    167  * both wake poll() up immediately.  The timeout is therefore only paid
    168  * by inputs that make MHD drop the connection without a reply.
    169  */
    170 #define THREAD_WAIT_MS 2
    171 
    172 /** Rounds of MHD_run() after each segment in the external shape. */
    173 #define PUMP_ROUNDS 3
    174 /** Rounds of MHD_run() after a segment sent with op 1 or 2. */
    175 #define PUMP_ROUNDS_LONG 10
    176 
    177 
    178 /* ------------------------------------------------------------------ */
    179 /* Per-iteration configuration                                         */
    180 /* ------------------------------------------------------------------ */
    181 
    182 struct fuzz_cfg
    183 {
    184   /** Daemon runs its own thread(s); the harness must not call MHD_run(). */
    185   int uses_threads;
    186   /** A real listening socket was requested (no MHD_USE_NO_LISTEN_SOCKET). */
    187   int listen_sock;
    188   /** MHD_USE_ERROR_LOG was requested, so an external logger is mandatory. */
    189   int err_log;
    190   /** 0 none, 1 suspend+resume in the handler, 2 resume from the pump. */
    191   int suspend_mode;
    192   /** 0 MHD_run(), 1 MHD_get_fdset2()+select()+MHD_run_from_select2(),
    193       2 MHD_run_wait(0), 3 the v1 MHD_get_fdset()/MHD_run_from_select(). */
    194   unsigned int loop_mode;
    195   /** Call MHD_quiesce_daemon() before stopping. */
    196   int quiesce;
    197   /** Query MHD_get_daemon_info() / MHD_get_timeout*() while pumping. */
    198   int daemon_info;
    199   /** Call MHD_set_connection_option() from the handler. */
    200   int conn_option;
    201   /** Which response constructor the handler uses. */
    202   unsigned int resp_kind;
    203   /** Handler answers MHD_NO instead of queueing a response. */
    204   int handler_no;
    205   /** Upper bound on the number of connections the iteration opens. */
    206   unsigned int nconn_max;
    207   /** Really connect() to the daemon's listening socket. */
    208   int real_connect;
    209   /** Install an accept policy callback, and what it should answer. */
    210   int accept_policy;
    211   int accept_policy_deny;
    212 };
    213 
    214 static struct fuzz_cfg cfg;
    215 
    216 /**
    217  * Connections suspended by suspend mode 2, which the pump loop still has
    218  * to resume.  Cleared by completed_cb() so that a connection MHD has
    219  * finished with is never resumed afterwards.  A connection that is still
    220  * suspended when MHD_stop_daemon() runs makes MHD answer with
    221  * MHD_PANIC ("MHD_stop_daemon() called while we have suspended
    222  * connections"), which would look exactly like an MHD bug.
    223  */
    224 static struct MHD_Connection *pending_resume[MAX_CONNECTIONS];
    225 
    226 /**
    227  * Set once the iteration only wants to drain the daemon.  The handler
    228  * then stops parking new connections, which is what makes the flush loop
    229  * in the teardown provably terminate.
    230  */
    231 static int tearing_down;
    232 
    233 /** Statistics, printed at exit with --verbose. */
    234 static unsigned long stat_daemons;
    235 static unsigned long stat_daemons_failed;
    236 static unsigned long stat_threaded;
    237 static unsigned long stat_handler_calls;
    238 static unsigned long stat_conns_added;
    239 static unsigned long stat_conns_refused;
    240 static unsigned long stat_real_conns;
    241 static int stats_registered;
    242 
    243 
    244 static void
    245 print_stats (void)
    246 {
    247   if (! fuzz_verbose)
    248     return;
    249   fprintf (stderr,
    250            "%s: daemons=%lu (failed to start=%lu, threaded=%lu) "
    251            "connections=%lu (refused=%lu, accepted from a real socket=%lu) "
    252            "handler calls=%lu\n",
    253            FUZZ_HARNESS_NAME,
    254            stat_daemons, stat_daemons_failed, stat_threaded,
    255            stat_conns_added, stat_conns_refused, stat_real_conns,
    256            stat_handler_calls);
    257 }
    258 
    259 
    260 /* ------------------------------------------------------------------ */
    261 /* Flags                                                               */
    262 /* ------------------------------------------------------------------ */
    263 
    264 /**
    265  * The event-loop / threading core of the flags word.  Every entry is a
    266  * combination MHD documents as valid, so that the ordinary path through
    267  * this harness gets a live daemon and actually exercises the option
    268  * handling; the deliberately invalid combinations are reached through
    269  * the raw escape of byte 2 instead.
    270  *
    271  * The distribution is on purpose: entries 0..17 are the external polling
    272  * modes, 18..23 the ones with internal threads.  An iteration with
    273  * internal threads costs a thread creation, a join and a short wait for
    274  * the answer, i.e. roughly an order of magnitude more than an external
    275  * one, so they are a quarter of the iterations rather than a half.
    276  */
    277 static const unsigned int mode_tbl[] = {
    278   0, 0, 0, 0, 0, 0,                              /* external, select()  */
    279   0, 0, 0, 0, 0, 0,
    280   MHD_USE_EPOLL, MHD_USE_EPOLL,                  /* external, epoll     */
    281   MHD_USE_EPOLL, MHD_USE_EPOLL,
    282   MHD_USE_AUTO, MHD_USE_AUTO,                    /* external, MHD picks */
    283   MHD_USE_INTERNAL_POLLING_THREAD,
    284   MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL,
    285   MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_EPOLL,
    286   MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
    287   MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD
    288   | MHD_USE_POLL,
    289   MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD
    290 };
    291 
    292 #define MODE_COUNT (sizeof (mode_tbl) / sizeof (mode_tbl[0]))
    293 
    294 /**
    295  * Flag bits the raw escape is allowed to set.  MHD_USE_TLS is masked
    296  * out: without a certificate the daemon merely fails to start, so it
    297  * would only waste iterations, and fuzzing GnuTLS is not what this
    298  * harness is for.  Everything else, including the bits above
    299  * MHD_USE_NO_THREAD_SAFETY that no MHD_FLAG uses, is fair game.
    300  */
    301 #define RAW_FLAG_MASK (~((unsigned int) MHD_USE_TLS))
    302 
    303 /**
    304  * The bit that MHD_suspend_connection() actually tests.
    305  *
    306  * MHD_ALLOW_SUSPEND_RESUME is a *compound* value (8192 | MHD_USE_ITC),
    307  * so "0 != (flags & MHD_ALLOW_SUSPEND_RESUME)" is already true for a
    308  * daemon that merely asked for MHD_USE_ITC -- and suspending such a
    309  * connection is answered with
    310  * MHD_PANIC ("Cannot suspend connections without enabling
    311  * MHD_ALLOW_SUSPEND_RESUME"), which is the harness violating the API
    312  * rather than a finding.  internal.h calls the single bit
    313  * MHD_TEST_ALLOW_SUSPEND_RESUME; this is the same value, expressed
    314  * without reaching into a private header.
    315  */
    316 #define SUSPEND_BIT \
    317         (((unsigned int) MHD_ALLOW_SUSPEND_RESUME) \
    318          & ~((unsigned int) MHD_USE_ITC))
    319 
    320 
    321 /**
    322  * Build the flags word from bytes 0, 1, 2 and 15 of the input.
    323  *
    324  * @param data the input
    325  * @return the flags to pass to MHD_start_daemon()
    326  */
    327 static unsigned int
    328 flags_from_input (const uint8_t *data)
    329 {
    330   unsigned int flags;
    331 
    332   if (0xC0 == (data[2] & 0xC0))
    333   {
    334     /* Raw escape: the flags word comes straight off the input.  This is
    335        what exercises MHD_start_daemon()'s combination checks (POLL with
    336        EPOLL, EPOLL with thread-per-connection, AUTO with either, ...),
    337        every one of which answers NULL. */
    338     flags = ((unsigned int) data[1])
    339             | (((unsigned int) (data[2] & 0x3F)) << 8)
    340             | (((unsigned int) data[15]) << 14);
    341     flags &= RAW_FLAG_MASK;
    342     cfg.listen_sock = (0 == (flags & MHD_USE_NO_LISTEN_SOCKET));
    343     cfg.err_log = (0 != (flags & MHD_USE_ERROR_LOG));
    344     return flags;
    345   }
    346 
    347   flags = mode_tbl[data[0] % MODE_COUNT];
    348 
    349   if (0 != (data[1] & 0x01))
    350     flags |= MHD_USE_PEDANTIC_CHECKS;
    351   if (0 != (data[1] & 0x02))
    352     flags |= MHD_USE_SUPPRESS_DATE_NO_CLOCK;
    353   if (0 != (data[1] & 0x04))
    354     flags |= MHD_ALLOW_SUSPEND_RESUME;
    355   if ( (0 != (data[1] & 0x08)) &&
    356        (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_UPGRADE)) )
    357     flags |= MHD_ALLOW_UPGRADE;
    358   if (0 != (data[1] & 0x10))
    359     flags |= MHD_USE_TURBO;
    360   if (0 != (data[1] & 0x20))
    361     flags |= MHD_USE_ITC;
    362   if (0 != (data[1] & 0x40))
    363     cfg.err_log = 1;
    364   if (0 != (data[1] & 0x80))
    365     flags |= MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT;   /* ignored without TLS */
    366 
    367   if (0 != (data[2] & 0x01))
    368     cfg.listen_sock = 1;
    369   if (0 != (data[2] & 0x02))
    370     flags |= MHD_USE_IPv6;
    371   if (0 != (data[2] & 0x04))
    372     flags |= MHD_USE_DUAL_STACK;
    373   if (0 != (data[2] & 0x08))
    374     flags |= MHD_USE_TCP_FASTOPEN;
    375   if (0 != (data[2] & 0x10))
    376     flags |= MHD_USE_NO_THREAD_SAFETY;
    377   if (0 != (data[2] & 0x20))
    378     flags |= MHD_USE_INSECURE_TLS_EARLY_DATA;       /* ignored without TLS */
    379 
    380   /* MHD_USE_NO_THREAD_SAFETY together with any internal thread is
    381      documented as unsupported and answered with NULL.  Drop it here
    382      rather than burning the iteration; the raw escape above still
    383      reaches that check. */
    384   if (0 != (flags & (MHD_USE_INTERNAL_POLLING_THREAD
    385                      | MHD_USE_THREAD_PER_CONNECTION)))
    386     flags &= ~((unsigned int) MHD_USE_NO_THREAD_SAFETY);
    387   return flags;
    388 }
    389 
    390 
    391 /**
    392  * @return non-zero if @a flags make MHD use epoll
    393  *
    394  * MHD_USE_AUTO resolves to epoll for everything except
    395  * thread-per-connection, which it resolves to poll.
    396  */
    397 static int
    398 uses_epoll (unsigned int flags)
    399 {
    400   if (0 != (flags & MHD_USE_EPOLL))
    401     return 1;
    402   return (0 != (flags & MHD_USE_AUTO)) &&
    403          (0 == (flags & MHD_USE_THREAD_PER_CONNECTION));
    404 }
    405 
    406 
    407 /**
    408  * Is the harness allowed to call MHD_quiesce_daemon() on an epoll
    409  * daemon that runs its own thread(s)?
    410  *
    411  * It is not, by default, because that combination reaches an *open* MHD
    412  * defect and would make "make check" fail at random:
    413  *
    414  *   MHD_quiesce_daemon() sets daemon->was_quiesced and then removes the
    415  *   listen FD from the epoll set itself (daemon.c:6208), tolerating
    416  *   ENOENT with the comment "can happen due to race with MHD_epoll()".
    417  *   MHD_epoll() removes the very same FD in two places.  The first
    418  *   (daemon.c:5556) mirrors that and tolerates ENOENT.  The second
    419  *   (daemon.c:5593), the "at the connection limit, disable listen
    420  *   socket" branch, also fires when daemon->was_quiesced is set -- and
    421  *   it does not tolerate anything:
    422  *
    423  *       if (0 != epoll_ctl (daemon->epoll_fd, EPOLL_CTL_DEL, ls, NULL))
    424  *         MHD_PANIC (_ ("Failed to remove listen FD from epoll set."));
    425  *
    426  *   The worker can read daemon->was_quiesced as already true and
    427  *   daemon->listen_socket_in_epoll as still true -- neither is atomic
    428  *   and neither is under a lock -- and then lose the race for the
    429  *   removal, so epoll_ctl() answers ENOENT and MHD aborts the process.
    430  *   Confirmed with errno == ENOENT, was_quiesced == 1, connections == 0.
    431  *   The same unguarded MHD_PANIC() sits in the worker-pool loop of
    432  *   MHD_quiesce_daemon() itself (daemon.c:6189).
    433  *
    434  * Set MHD_FUZZ_QUIESCE_EPOLL_RACE=1 to reach it.  Quiescing is left
    435  * enabled everywhere else, so the poll()/select() side of
    436  * MHD_quiesce_daemon(), including its worker-pool loop, keeps being
    437  * exercised.
    438  */
    439 static int
    440 quiesce_epoll_race_allowed (void)
    441 {
    442   static int val = -1;
    443 
    444   if (0 > val)
    445   {
    446     const char *e = getenv ("MHD_FUZZ_QUIESCE_EPOLL_RACE");
    447 
    448     val = ((NULL != e) && (0 != atoi (e))) ? 1 : 0;
    449   }
    450   return val;
    451 }
    452 
    453 
    454 /* ------------------------------------------------------------------ */
    455 /* Option values                                                       */
    456 /* ------------------------------------------------------------------ */
    457 
    458 static const size_t mem_limit_tbl[] = {
    459   0 /* MHD default */, 128, 192, 256, 384, 512, 1024, 1400,
    460   1500, 2048, 4096, 8192, 32768, 64, 0, 0
    461 };
    462 
    463 static const size_t mem_increment_tbl[] = {
    464   0 /* MHD default */, 1, 16, 64, 128, 256, 1024, 4096,
    465   1500, 32768, 0, 0, 0, 0, 0, 0
    466 };
    467 
    468 static const unsigned int conn_limit_tbl[] = {
    469   0, 1, 2, 3, 8, 64, 1024, 100000
    470 };
    471 
    472 static const unsigned int per_ip_limit_tbl[] = {
    473   0, 1, 2, 3, 4, 8, 64, 1000
    474 };
    475 
    476 static const unsigned int timeout_tbl[] = {
    477   0, 1, 2, 5, 60, 3600, 86400, UINT_MAX
    478 };
    479 
    480 static const unsigned int pool_size_tbl[] = { 2, 3, 4, 2 };
    481 
    482 /* Small stacks make pthread_create() fail outright under ASAN, which
    483    only produces a NULL daemon; keep the values plausible. */
    484 static const size_t stack_size_tbl[] = {
    485   0, 1024u * 1024u, 2048u * 1024u, 8192u * 1024u
    486 };
    487 
    488 /* Bounded on purpose: the nonce-nc array is nonce_nc_size *
    489    sizeof(struct MHD_NonceNc) (about 130 bytes per slot) and is
    490    allocated and freed once per iteration. */
    491 static const unsigned int nonce_nc_tbl[] = { 0, 1, 4, 32 };
    492 
    493 static const int discipline_tbl[] = { -3, -2, -1, 0, 1, 2, 3, -4 };
    494 
    495 static const int strict_tbl[] = { -1, 0, 1, 2 };
    496 
    497 static const unsigned int backlog_tbl[] = { 0, 1, 5, 511 };
    498 
    499 static const unsigned int fastopen_tbl[] = { 0, 1, 5, 10 };
    500 
    501 /* Anything but the platform's own FD_SETSIZE is rejected unless MHD was
    502    built with HAS_FD_SETSIZE_OVERRIDABLE, so the odd values are a small
    503    minority: they cost a whole iteration each. */
    504 static const int fd_setsize_tbl[] = {
    505   (int) FD_SETSIZE, (int) FD_SETSIZE, (int) FD_SETSIZE, (int) FD_SETSIZE,
    506   (int) FD_SETSIZE, (int) FD_SETSIZE, 64, 0
    507 };
    508 
    509 /** Fixed entropy, so that a digest nonce is reproducible across runs. */
    510 static const char digest_rnd[32] =
    511   "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
    512   "\xfe\xdc\xba\x98\x76\x54\x32\x10\xfe\xdc\xba\x98\x76\x54\x32\x10";
    513 
    514 /* Bind addresses for MHD_OPTION_SOCK_ADDR / MHD_OPTION_SOCK_ADDR_LEN.
    515    Filled in by prepare_sock_addrs() because htons()/htonl() are not
    516    constant expressions. */
    517 static struct sockaddr_in bind4;
    518 #ifdef AF_INET6
    519 static struct sockaddr_in6 bind6;
    520 #endif
    521 static int bind_addrs_ready;
    522 
    523 
    524 static void
    525 prepare_sock_addrs (void)
    526 {
    527   if (bind_addrs_ready)
    528     return;
    529   bind_addrs_ready = 1;
    530   memset (&bind4, 0, sizeof (bind4));
    531   bind4.sin_family = AF_INET;
    532   bind4.sin_port = htons (0);            /* ephemeral */
    533   bind4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    534 #ifdef AF_INET6
    535   memset (&bind6, 0, sizeof (bind6));
    536   bind6.sin6_family = AF_INET6;
    537   bind6.sin6_port = htons (0);
    538   bind6.sin6_addr = in6addr_loopback;
    539 #endif
    540 }
    541 
    542 
    543 /* ------------------------------------------------------------------ */
    544 /* The daemon callbacks                                                */
    545 /* ------------------------------------------------------------------ */
    546 
    547 /**
    548  * MHD_OPTION_EXTERNAL_LOGGER.  Swallows the message unless --verbose is
    549  * in effect.  This is what makes MHD_USE_ERROR_LOG affordable: with the
    550  * flag set, MHD executes several hundred MHD_DLOG() call sites in
    551  * daemon.c that are otherwise dead, and without a logger of our own all
    552  * of that would land on stderr.
    553  */
    554 static void
    555 logger_cb (void *cls,
    556            const char *fmt,
    557            va_list ap)
    558 {
    559   (void) cls;
    560   if (! fuzz_verbose)
    561     return;
    562   (void) vfprintf (stderr, fmt, ap);
    563 }
    564 
    565 
    566 /**
    567  * MHD_OPTION_URI_LOG_CALLBACK.  The return value becomes the initial
    568  * `*req_cls` of the request, so it has to stay NULL: the access handler
    569  * uses "req_cls is still NULL" to recognise its first invocation, and a
    570  * non-NULL value here would also have to be freed somewhere, which is
    571  * not possible when MHD_OPTION_NOTIFY_COMPLETED is not set.
    572  */
    573 static void *
    574 uri_log_cb (void *cls,
    575             const char *uri,
    576             struct MHD_Connection *con)
    577 {
    578   volatile size_t sink;
    579 
    580   (void) cls;
    581   (void) con;
    582   sink = (NULL != uri) ? strlen (uri) : 0;
    583   (void) sink;
    584   return NULL;
    585 }
    586 
    587 
    588 /**
    589  * MHD_OPTION_UNESCAPE_CALLBACK.  Replaces MHD's own unescaping, so it
    590  * must honour the contract: unescape @a s in place and return the new
    591  * length.  Leaving the string alone is a legal implementation and keeps
    592  * the harness out of the business of re-testing mhd_str.c, which
    593  * fuzz_str does.
    594  */
    595 static size_t
    596 unescape_cb (void *cls,
    597              struct MHD_Connection *conn,
    598              char *s)
    599 {
    600   (void) cls;
    601   (void) conn;
    602   return strlen (s);
    603 }
    604 
    605 
    606 static void
    607 completed_cb (void *cls,
    608               struct MHD_Connection *connection,
    609               void **req_cls,
    610               enum MHD_RequestTerminationCode toe)
    611 {
    612   (void) cls;
    613   (void) toe;
    614   /* MHD is done with this connection, so the deferred resume of suspend
    615      mode 2 must not fire for it any more. */
    616   if (! cfg.uses_threads)
    617   {
    618     unsigned int i;
    619 
    620     for (i = 0; i < MAX_CONNECTIONS; i++)
    621       if (pending_resume[i] == connection)
    622         pending_resume[i] = NULL;
    623   }
    624   *req_cls = NULL;
    625 }
    626 
    627 
    628 static void
    629 notify_connection_cb (void *cls,
    630                       struct MHD_Connection *connection,
    631                       void **socket_context,
    632                       enum MHD_ConnectionNotificationCode toe)
    633 {
    634   (void) cls;
    635   (void) connection;
    636   if (MHD_CONNECTION_NOTIFY_STARTED == toe)
    637     *socket_context = NULL;
    638 }
    639 
    640 
    641 static void
    642 panic_cb (void *cls,
    643           const char *file,
    644           unsigned int line,
    645           const char *reason)
    646 {
    647   char msg[512];
    648 
    649   (void) cls;
    650   (void) snprintf (msg, sizeof (msg),
    651                    "MHD_PANIC() reached at %s:%u: %s",
    652                    (NULL != file) ? file : "?",
    653                    line,
    654                    (NULL != reason) ? reason : "?");
    655   fuzz_report_finding (msg);
    656 }
    657 
    658 
    659 /* ------------------------------------------------------------------ */
    660 /* Suspend bookkeeping                                                 */
    661 /* ------------------------------------------------------------------ */
    662 
    663 static void
    664 pending_resume_add (struct MHD_Connection *c)
    665 {
    666   unsigned int i;
    667 
    668   for (i = 0; i < MAX_CONNECTIONS; i++)
    669   {
    670     if (NULL == pending_resume[i])
    671     {
    672       pending_resume[i] = c;
    673       return;
    674     }
    675   }
    676 }
    677 
    678 
    679 /**
    680  * Resume everything still parked.
    681  *
    682  * @return non-zero if at least one connection was resumed, so that the
    683  *         caller knows the daemon needs another round to act on it
    684  */
    685 static int
    686 pending_resume_flush (void)
    687 {
    688   unsigned int i;
    689   int any = 0;
    690 
    691   for (i = 0; i < MAX_CONNECTIONS; i++)
    692   {
    693     struct MHD_Connection *c = pending_resume[i];
    694 
    695     if (NULL == c)
    696       continue;
    697     /* Clear first: MHD_resume_connection() can make MHD run the handler,
    698        which may suspend the very same connection again. */
    699     pending_resume[i] = NULL;
    700     MHD_resume_connection (c);
    701     any = 1;
    702   }
    703   return any;
    704 }
    705 
    706 
    707 /**
    708  * Suspend the connection if the input asks for it.  Only ever called in
    709  * the external-polling shape: resuming from the harness thread while an
    710  * internal worker owns the connection is legal but untimed, and this
    711  * harness has no way to tell whether the resume happened before or after
    712  * the worker looked at the connection.
    713  */
    714 static void
    715 suspend_maybe (struct MHD_Connection *connection)
    716 {
    717   if ( (0 == cfg.suspend_mode) ||
    718        cfg.uses_threads ||
    719        tearing_down)
    720     return;
    721   MHD_suspend_connection (connection);
    722   if (1 == cfg.suspend_mode)
    723   {
    724     MHD_resume_connection (connection);
    725     return;
    726   }
    727   pending_resume_add (connection);
    728 }
    729 
    730 
    731 /* ------------------------------------------------------------------ */
    732 /* The access handler                                                  */
    733 /* ------------------------------------------------------------------ */
    734 
    735 static const char resp_body[] = "hello";
    736 
    737 static enum MHD_Result
    738 ahc (void *cls,
    739      struct MHD_Connection *connection,
    740      const char *url,
    741      const char *method,
    742      const char *version,
    743      const char *upload_data,
    744      size_t *upload_data_size,
    745      void **req_cls)
    746 {
    747   /* The address of this object is the "request already started" marker.
    748      Nothing is allocated per request on purpose: this harness runs
    749      millions of iterations in one process and the daemon shapes with
    750      internal threads cannot guarantee that MHD_OPTION_NOTIFY_COMPLETED
    751      is even set, so anything malloc()ed here could leak. */
    752   static int req_marker;
    753   struct MHD_Response *resp;
    754   enum MHD_Result ret;
    755   unsigned int code;
    756   volatile size_t sink = 0;
    757 
    758   (void) cls;
    759   (void) upload_data;
    760 
    761   if (&req_marker != *req_cls)
    762   {
    763     *req_cls = &req_marker;
    764     return MHD_YES;
    765   }
    766   stat_handler_calls++;
    767 
    768   /* Touch the parsed request line the way a real application would. */
    769   if (NULL != url)
    770     sink += strlen (url);
    771   if (NULL != method)
    772     sink += strlen (method);
    773   if (NULL != version)
    774     sink += strlen (version);
    775   (void) sink;
    776 
    777   if (0 != *upload_data_size)
    778   {
    779     *upload_data_size = 0;
    780     return MHD_YES;
    781   }
    782 
    783   if (cfg.conn_option)
    784     (void) MHD_set_connection_option (connection,
    785                                       MHD_CONNECTION_OPTION_TIMEOUT,
    786                                       (unsigned int) 30);
    787   if (cfg.handler_no)
    788     return MHD_NO;    /* never suspend on this path: MHD_NO terminates the
    789                          connection and terminating a suspended one trips
    790                          mhd_assert (! connection->suspended) */
    791 
    792   code = MHD_HTTP_OK;
    793   switch (cfg.resp_kind)
    794   {
    795   case 1:
    796     resp = MHD_create_response_empty (MHD_RF_NONE);
    797     code = MHD_HTTP_NO_CONTENT;
    798     break;
    799   case 2:
    800     resp = MHD_create_response_from_buffer (sizeof (resp_body) - 1,
    801                                             (void *) (intptr_t) resp_body,
    802                                             MHD_RESPMEM_MUST_COPY);
    803     code = MHD_HTTP_FORBIDDEN;
    804     break;
    805   case 3:
    806     resp = MHD_create_response_from_buffer_static (0, "");
    807     code = MHD_HTTP_INTERNAL_SERVER_ERROR;
    808     break;
    809   default:
    810     resp = MHD_create_response_from_buffer_static (sizeof (resp_body) - 1,
    811                                                    resp_body);
    812     break;
    813   }
    814   if (NULL == resp)
    815     return MHD_NO;
    816   ret = MHD_queue_response (connection, code, resp);
    817   MHD_destroy_response (resp);
    818   if (MHD_YES == ret)
    819     suspend_maybe (connection);
    820   return ret;
    821 }
    822 
    823 
    824 /* ------------------------------------------------------------------ */
    825 /* Driving the daemon                                                  */
    826 /* ------------------------------------------------------------------ */
    827 
    828 /**
    829  * Read and discard whatever the daemon has produced so far.  The harness
    830  * has no response oracle -- fuzz_request owns that job -- but the data
    831  * has to be taken off the socket so that MHD's writes keep succeeding.
    832  */
    833 static void
    834 drain (int sock)
    835 {
    836   char tmp[RESP_DRAIN_BUF];
    837 
    838   if (0 > sock)
    839     return;
    840   while (0 < recv (sock, tmp, sizeof (tmp), MSG_DONTWAIT))
    841     /* nothing */;
    842 }
    843 
    844 
    845 /**
    846  * Advance an externally polled daemon by one cycle, through whichever of
    847  * the four event-loop entry points byte 12 selected.
    848  *
    849  * The select() timeout is always zero: the harness is single threaded
    850  * and everything the daemon could be waiting for has already been
    851  * written into the socketpair, so blocking would only burn wall clock.
    852  */
    853 static void
    854 run_once (struct MHD_Daemon *d)
    855 {
    856   fd_set rs;
    857   fd_set ws;
    858   fd_set es;
    859   MHD_socket max_fd = MHD_INVALID_SOCKET;
    860   struct timeval tv;
    861 
    862   if (cfg.daemon_info)
    863   {
    864     MHD_UNSIGNED_LONG_LONG tl = 0;
    865     volatile int64_t sink;
    866 
    867     (void) MHD_get_timeout (d, &tl);
    868     sink = MHD_get_timeout64s (d);
    869     sink += (int64_t) MHD_get_timeout_i (d);
    870     (void) sink;
    871   }
    872   switch (cfg.loop_mode)
    873   {
    874   case 1:
    875   case 3:
    876     FD_ZERO (&rs);
    877     FD_ZERO (&ws);
    878     FD_ZERO (&es);
    879     /* MHD_get_fdset and MHD_run_from_select are also macros forwarding
    880        to the *2 variants, so the names have to be parenthesised for the
    881        v1 entry points to be reached at all. */
    882     if (1 == cfg.loop_mode)
    883     {
    884       if (MHD_YES != MHD_get_fdset2 (d, &rs, &ws, &es, &max_fd,
    885                                      (unsigned int) FD_SETSIZE))
    886       {
    887         (void) MHD_run (d);
    888         return;
    889       }
    890     }
    891     else
    892     {
    893       if (MHD_YES != (MHD_get_fdset) (d, &rs, &ws, &es, &max_fd))
    894       {
    895         (void) MHD_run (d);
    896         return;
    897       }
    898     }
    899     tv.tv_sec = 0;
    900     tv.tv_usec = 0;
    901     if (MHD_INVALID_SOCKET != max_fd)
    902       (void) select ((int) max_fd + 1, &rs, &ws, &es, &tv);
    903     if (1 == cfg.loop_mode)
    904       (void) MHD_run_from_select2 (d, &rs, &ws, &es, (unsigned int) FD_SETSIZE);
    905     else
    906       (void) (MHD_run_from_select) (d, &rs, &ws, &es);
    907     break;
    908   case 2:
    909     (void) MHD_run_wait (d, 0);
    910     break;
    911   default:
    912     (void) MHD_run (d);
    913     break;
    914   }
    915 }
    916 
    917 
    918 static void
    919 pump (struct MHD_Daemon *d,
    920       int sock,
    921       unsigned int rounds)
    922 {
    923   unsigned int i;
    924 
    925   if (cfg.uses_threads)
    926     return;
    927   for (i = 0; i < rounds; i++)
    928   {
    929     /* Deferred resume of suspend mode 2.  Each slot is cleared before
    930        its connection is resumed, which stays correct even when the
    931        resume makes MHD complete (and forget) the connection. */
    932     (void) pending_resume_flush ();
    933     run_once (d);
    934     drain (sock);
    935   }
    936 }
    937 
    938 
    939 /**
    940  * Wait, briefly and with a hard bound, for a daemon with internal
    941  * threads to answer.  The caller has already shut the write side down,
    942  * so MHD sees end-of-stream and either answers or closes; both wake
    943  * poll() immediately.  An input that makes MHD do neither pays the full
    944  * timeout, which is why it is only a couple of milliseconds.
    945  */
    946 static void
    947 wait_threaded (int sock)
    948 {
    949   unsigned int round;
    950 
    951   if (0 > sock)
    952     return;
    953   for (round = 0; round < 4; round++)
    954   {
    955     struct pollfd p;
    956     char tmp[RESP_DRAIN_BUF];
    957     ssize_t n;
    958 
    959     p.fd = sock;
    960     p.events = POLLIN;
    961     p.revents = 0;
    962     if (0 >= poll (&p, 1, THREAD_WAIT_MS))
    963       return;
    964     if (0 == (p.revents & POLLIN))
    965       return;                   /* POLLHUP/POLLERR only: peer is gone */
    966     n = recv (sock, tmp, sizeof (tmp), MSG_DONTWAIT);
    967     if (0 >= n)
    968       return;
    969   }
    970 }
    971 
    972 
    973 static void
    974 send_all (struct MHD_Daemon *d,
    975           int sock,
    976           const uint8_t *data,
    977           size_t len)
    978 {
    979   size_t off = 0;
    980   unsigned int stall = 0;
    981 
    982   if (0 > sock)
    983     return;
    984   while ( (off < len) &&
    985           (stall < 64) )
    986   {
    987     ssize_t s = send (sock, data + off, len - off, MSG_DONTWAIT);
    988 
    989     if (0 < s)
    990     {
    991       off += (size_t) s;
    992       stall = 0;
    993       continue;
    994     }
    995     stall++;
    996     if (cfg.uses_threads)
    997     {
    998       struct pollfd p;
    999 
   1000       p.fd = sock;
   1001       p.events = POLLOUT;
   1002       p.revents = 0;
   1003       if (0 >= poll (&p, 1, THREAD_WAIT_MS))
   1004         break;
   1005     }
   1006     else
   1007     {
   1008       pump (d, sock, 2);
   1009     }
   1010     if ( (0 > s) &&
   1011          (EAGAIN != errno) &&
   1012          (EWOULDBLOCK != errno) &&
   1013          (EINTR != errno) )
   1014       break;
   1015   }
   1016 }
   1017 
   1018 
   1019 /**
   1020  * Hand a fresh socketpair to the daemon.
   1021  *
   1022  * @param d the daemon
   1023  * @param[out] sock set to the harness side of the pair
   1024  * @return 0 on success, -1 if MHD refused the connection (which is a
   1025  *         perfectly ordinary outcome: MHD_OPTION_CONNECTION_LIMIT and
   1026  *         MHD_OPTION_PER_IP_CONNECTION_LIMIT are part of what is fuzzed)
   1027  */
   1028 static int
   1029 new_connection (struct MHD_Daemon *d,
   1030                 int *sock)
   1031 {
   1032   int sv[2];
   1033   struct sockaddr_in sa;
   1034 
   1035   *sock = -1;
   1036   if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
   1037     return -1;
   1038   memset (&sa, 0, sizeof (sa));
   1039   sa.sin_family = AF_INET;
   1040   sa.sin_port = htons (44444);
   1041   sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
   1042   if (MHD_YES != MHD_add_connection (d,
   1043                                      (MHD_socket) sv[1],
   1044                                      (const struct sockaddr *) &sa,
   1045                                      (socklen_t) sizeof (sa)))
   1046   {
   1047     /* MHD has already closed sv[1] in that case */
   1048     (void) close (sv[0]);
   1049     stat_conns_refused++;
   1050     return -1;
   1051   }
   1052   stat_conns_added++;
   1053   *sock = sv[0];
   1054   return 0;
   1055 }
   1056 
   1057 
   1058 static void
   1059 close_connection (struct MHD_Daemon *d,
   1060                   int *sock)
   1061 {
   1062   if (0 > *sock)
   1063     return;
   1064   (void) shutdown (*sock, SHUT_WR);
   1065   if (cfg.uses_threads)
   1066     wait_threaded (*sock);
   1067   else
   1068     pump (d, *sock, 4);
   1069   (void) close (*sock);
   1070   *sock = -1;
   1071 }
   1072 
   1073 
   1074 /* ------------------------------------------------------------------ */
   1075 /* Building the option array                                           */
   1076 /* ------------------------------------------------------------------ */
   1077 
   1078 #define PICK(tbl, idx) ((tbl)[(idx) % (sizeof (tbl) / sizeof ((tbl)[0]))])
   1079 
   1080 static void
   1081 add_opt (struct MHD_OptionItem *opts,
   1082          unsigned int *nopt,
   1083          enum MHD_OPTION option,
   1084          intptr_t value,
   1085          void *ptr_value)
   1086 {
   1087   if (*nopt + 1 >= MAX_OPTS)
   1088     return;
   1089   opts[*nopt].option = option;
   1090   opts[*nopt].value = value;
   1091   opts[*nopt].ptr_value = ptr_value;
   1092   (*nopt)++;
   1093 }
   1094 
   1095 
   1096 /**
   1097  * Translate the presence masks (bytes 3, 4, 14) and the value selectors
   1098  * (bytes 6..11, 15) into an MHD_OptionItem array.
   1099  *
   1100  * Only the options that can be expressed through MHD_OPTION_ARRAY are
   1101  * built here.  The five callback options take two pointers, and putting
   1102  * a function pointer into the array's `intptr_t value` member is not
   1103  * strictly conforming C, so those go through the varargs of
   1104  * MHD_start_daemon() instead (see start_daemon_variant()).
   1105  */
   1106 static unsigned int
   1107 build_options (const uint8_t *data,
   1108                struct MHD_OptionItem *opts,
   1109                unsigned int flags)
   1110 {
   1111   unsigned int nopt = 0;
   1112   const uint8_t mask_a = data[3];
   1113   const uint8_t mask_b = data[4];
   1114   const uint8_t mask_d = data[14];
   1115   /* A thread pool needs an internal polling thread and is incompatible
   1116      with thread-per-connection. */
   1117   const int pool_ok =
   1118     (0 != (flags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
   1119     (0 == (flags & MHD_USE_THREAD_PER_CONNECTION));
   1120   /* Offer options in configurations where MHD rejects them.  One input
   1121      in eight: the rejection branches are worth reaching, but each one
   1122      costs the whole rest of the iteration, because the daemon does not
   1123      start at all. */
   1124   const int misfit = (0xE0 == (data[15] & 0xE0));
   1125 
   1126   if (0 != (mask_a & 0x01))
   1127     add_opt (opts, &nopt, MHD_OPTION_CONNECTION_MEMORY_LIMIT,
   1128              (intptr_t) PICK (mem_limit_tbl, data[6] & 0x0F), NULL);
   1129   if (0 != (mask_a & 0x02))
   1130     add_opt (opts, &nopt, MHD_OPTION_CONNECTION_MEMORY_INCREMENT,
   1131              (intptr_t) PICK (mem_increment_tbl, (data[6] >> 4) & 0x0F), NULL);
   1132   if (0 != (mask_a & 0x04))
   1133     add_opt (opts, &nopt, MHD_OPTION_CONNECTION_LIMIT,
   1134              (intptr_t) PICK (conn_limit_tbl, data[7] & 0x07), NULL);
   1135   if (0 != (mask_a & 0x08))
   1136     add_opt (opts, &nopt, MHD_OPTION_PER_IP_CONNECTION_LIMIT,
   1137              (intptr_t) PICK (per_ip_limit_tbl, (data[7] >> 4) & 0x07), NULL);
   1138   if (0 != (mask_a & 0x10))
   1139     add_opt (opts, &nopt, MHD_OPTION_CONNECTION_TIMEOUT,
   1140              (intptr_t) PICK (timeout_tbl, data[8] & 0x07), NULL);
   1141   /* MHD_OPTION_THREAD_POOL_SIZE is rejected outright without an
   1142      internal polling thread, and again when combined with
   1143      MHD_USE_THREAD_PER_CONNECTION.  Both branches are worth reaching,
   1144      but a daemon that fails to start exercises nothing else, so the
   1145      mismatched combinations are gated behind an extra bit instead of
   1146      being half of all the inputs that name the option. */
   1147   if ( (0 != (mask_a & 0x20)) &&
   1148        (pool_ok || misfit) )
   1149     add_opt (opts, &nopt, MHD_OPTION_THREAD_POOL_SIZE,
   1150              (intptr_t) PICK (pool_size_tbl, (data[8] >> 3) & 0x03), NULL);
   1151   if (0 != (mask_a & 0x40))
   1152     add_opt (opts, &nopt, MHD_OPTION_THREAD_STACK_SIZE,
   1153              (intptr_t) PICK (stack_size_tbl, (data[8] >> 5) & 0x03), NULL);
   1154   if (0 != (mask_a & 0x80))
   1155     add_opt (opts, &nopt, MHD_OPTION_LISTENING_ADDRESS_REUSE,
   1156              (intptr_t) (unsigned int) (data[11] & 0x01), NULL);
   1157 
   1158   if (0 != (mask_b & 0x01))
   1159     add_opt (opts, &nopt, MHD_OPTION_LISTEN_BACKLOG_SIZE,
   1160              (intptr_t) PICK (backlog_tbl, (data[11] >> 1) & 0x03), NULL);
   1161   if (0 != (mask_b & 0x02))
   1162     add_opt (opts, &nopt, MHD_OPTION_NONCE_NC_SIZE,
   1163              (intptr_t) PICK (nonce_nc_tbl, data[9] & 0x03), NULL);
   1164   if (0 != (mask_b & 0x04))
   1165     add_opt (opts, &nopt, MHD_OPTION_SERVER_INSANITY,
   1166              (intptr_t) (unsigned int) ((data[10] >> 6) & 0x03), NULL);
   1167   if (0 != (mask_b & 0x08))
   1168     add_opt (opts, &nopt, MHD_OPTION_STRICT_FOR_CLIENT,
   1169              (intptr_t) PICK (strict_tbl, (data[10] >> 4) & 0x03), NULL);
   1170   if (0 != (mask_b & 0x10))
   1171     add_opt (opts, &nopt, MHD_OPTION_CLIENT_DISCIPLINE_LVL,
   1172              (intptr_t) PICK (discipline_tbl, data[10] & 0x07), NULL);
   1173   if (0 != (mask_b & 0x20))
   1174     add_opt (opts, &nopt, MHD_OPTION_SIGPIPE_HANDLED_BY_APP,
   1175              /* Truthful: LLVMFuzzerTestOneInput() ignores SIGPIPE
   1176                 process-wide before anything else happens. */
   1177              (intptr_t) 1, NULL);
   1178   if (0 != (mask_b & 0x40))
   1179     add_opt (opts, &nopt, MHD_OPTION_APP_FD_SETSIZE,
   1180              (intptr_t) PICK (fd_setsize_tbl, (data[11] >> 3) & 0x07), NULL);
   1181   if (0 != (mask_b & 0x80))
   1182     add_opt (opts, &nopt, MHD_OPTION_ALLOW_BIN_ZERO_IN_URI_PATH,
   1183              (intptr_t) (int) ((data[11] >> 5) & 0x03), NULL);
   1184 
   1185   if (0 != (mask_d & 0x01))
   1186     add_opt (opts, &nopt, MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE,
   1187              (intptr_t) (unsigned int) ((data[9] >> 2) & 0x0F), NULL);
   1188   if (0 != (mask_d & 0x02))
   1189     add_opt (opts, &nopt, MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT,
   1190              (intptr_t) (unsigned int) (data[15] & 0x7F), NULL);
   1191   if (0 != (mask_d & 0x04))
   1192     add_opt (opts, &nopt, MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC,
   1193              (intptr_t) (uint32_t) data[15], NULL);
   1194   if (0 != (mask_d & 0x08))
   1195     add_opt (opts, &nopt, MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE,
   1196              (intptr_t) PICK (fastopen_tbl, (data[11] >> 6) & 0x03), NULL);
   1197   if (0 != (mask_d & 0x10))
   1198     add_opt (opts, &nopt, MHD_OPTION_TLS_NO_ALPN,
   1199              (intptr_t) (int) (data[15] & 0x01), NULL);
   1200   if (0 != (mask_d & 0x20))
   1201     /* MHD_INVALID_SOCKET means "use the socket MHD creates itself"; a
   1202        real descriptor is deliberately not offered, because MHD takes
   1203        ownership of it and the harness would have to track that. */
   1204     add_opt (opts, &nopt, MHD_OPTION_LISTEN_SOCKET,
   1205              (intptr_t) MHD_INVALID_SOCKET, NULL);
   1206 
   1207   /* MHD_OPTION_DIGEST_AUTH_RANDOM keeps the caller's buffer, the _COPY
   1208      variant makes MHD malloc() a copy that MHD_stop_daemon() has to free
   1209      again -- a leak this harness would notice immediately. */
   1210   if (0 != (data[5] & 0x20))
   1211     add_opt (opts, &nopt,
   1212              (0 != (data[5] & 0x40))
   1213              ? MHD_OPTION_DIGEST_AUTH_RANDOM_COPY
   1214              : MHD_OPTION_DIGEST_AUTH_RANDOM,
   1215              (intptr_t) sizeof (digest_rnd),
   1216              (void *) (intptr_t) digest_rnd);
   1217 
   1218   /* A bind address is rejected together with MHD_USE_NO_LISTEN_SOCKET;
   1219      same reasoning as for the thread pool above. */
   1220   if ( (0 != (data[5] & 0x80)) &&
   1221        (cfg.listen_sock || misfit) )
   1222   {
   1223     prepare_sock_addrs ();
   1224     /* The address family has to match MHD_USE_IPv6, otherwise MHD
   1225        rejects the daemon; that check is reached through the raw flag
   1226        escape rather than by feeding a mismatched address on purpose. */
   1227 #ifdef AF_INET6
   1228     if (0 != (flags & MHD_USE_IPv6))
   1229     {
   1230       if (0 != (data[15] & 0x02))
   1231         add_opt (opts, &nopt, MHD_OPTION_SOCK_ADDR_LEN,
   1232                  (intptr_t) (socklen_t) sizeof (bind6), &bind6);
   1233       else
   1234         add_opt (opts, &nopt, MHD_OPTION_SOCK_ADDR, 0, &bind6);
   1235     }
   1236     else
   1237 #endif
   1238     if (0 != (data[15] & 0x02))
   1239       add_opt (opts, &nopt, MHD_OPTION_SOCK_ADDR_LEN,
   1240                (intptr_t) (socklen_t) sizeof (bind4), &bind4);
   1241     else
   1242       add_opt (opts, &nopt, MHD_OPTION_SOCK_ADDR, 0, &bind4);
   1243   }
   1244 
   1245   /* An option number MHD does not know at all.  parse_options_va()
   1246      answers MHD_NO for it and MHD_start_daemon() returns NULL, which is
   1247      the branch this reaches; keep it last so that everything above has
   1248      already been parsed. */
   1249   if (0 != (mask_d & 0x40))
   1250     add_opt (opts, &nopt, (enum MHD_OPTION) (200 + (data[15] & 0x0F)),
   1251              0, NULL);
   1252 
   1253   opts[nopt].option = MHD_OPTION_END;
   1254   opts[nopt].value = 0;
   1255   opts[nopt].ptr_value = NULL;
   1256   return nopt;
   1257 }
   1258 
   1259 
   1260 /* The three callback options whose "not set" state is representable as a
   1261    NULL function pointer; MHD checks all three for NULL before calling
   1262    them, so passing NULL is exactly equivalent to omitting the option. */
   1263 typedef void *(*fuzz_uri_log_cb)(void *, const char *,
   1264                                  struct MHD_Connection *);
   1265 
   1266 #define VARARG_CALLBACKS \
   1267         MHD_OPTION_NOTIFY_COMPLETED, cb_completed, NULL, \
   1268         MHD_OPTION_NOTIFY_CONNECTION, cb_notify, NULL, \
   1269         MHD_OPTION_URI_LOG_CALLBACK, cb_uri_log, NULL
   1270 
   1271 /* The accept policy callback, defined with the accept path further
   1272    down. */
   1273 static enum MHD_Result
   1274 apc_cb (void *cls,
   1275         const struct sockaddr *addr,
   1276         socklen_t addrlen);
   1277 
   1278 
   1279 /**
   1280  * Start the daemon.
   1281  *
   1282  * MHD_OPTION_EXTERNAL_LOGGER and MHD_OPTION_UNESCAPE_CALLBACK cannot be
   1283  * "passed as NULL": MHD calls both unconditionally, so their absence has
   1284  * to be expressed by leaving the option out of the varargs, which is why
   1285  * there are four spellings of the same call.  The logger comes first on
   1286  * purpose -- MHD_OPTION_EXTERNAL_LOGGER only catches the messages
   1287  * emitted after it has been parsed, and parsing the option array emits
   1288  * several.
   1289  */
   1290 static struct MHD_Daemon *
   1291 start_daemon_variant (unsigned int flags,
   1292                       struct MHD_OptionItem *opts,
   1293                       unsigned int cbsel)
   1294 {
   1295   MHD_AcceptPolicyCallback apc = cfg.accept_policy ? &apc_cb : NULL;
   1296   MHD_RequestCompletedCallback cb_completed =
   1297     (0 != (cbsel & 0x01)) ? &completed_cb : NULL;
   1298   MHD_NotifyConnectionCallback cb_notify =
   1299     (0 != (cbsel & 0x02)) ? &notify_connection_cb : NULL;
   1300   fuzz_uri_log_cb cb_uri_log =
   1301     (0 != (cbsel & 0x04)) ? &uri_log_cb : NULL;
   1302 
   1303   switch ((cbsel >> 3) & 0x03)
   1304   {
   1305   case 1:
   1306     return MHD_start_daemon (flags, 0, apc, NULL, &ahc, NULL,
   1307                              MHD_OPTION_ARRAY, opts,
   1308                              VARARG_CALLBACKS,
   1309                              MHD_OPTION_UNESCAPE_CALLBACK, &unescape_cb, NULL,
   1310                              MHD_OPTION_END);
   1311   case 2:
   1312     return MHD_start_daemon (flags, 0, apc, NULL, &ahc, NULL,
   1313                              MHD_OPTION_EXTERNAL_LOGGER, &logger_cb, NULL,
   1314                              MHD_OPTION_ARRAY, opts,
   1315                              VARARG_CALLBACKS,
   1316                              MHD_OPTION_END);
   1317   case 3:
   1318     return MHD_start_daemon (flags, 0, apc, NULL, &ahc, NULL,
   1319                              MHD_OPTION_EXTERNAL_LOGGER, &logger_cb, NULL,
   1320                              MHD_OPTION_ARRAY, opts,
   1321                              VARARG_CALLBACKS,
   1322                              MHD_OPTION_UNESCAPE_CALLBACK, &unescape_cb, NULL,
   1323                              MHD_OPTION_END);
   1324   default:
   1325     return MHD_start_daemon (flags, 0, apc, NULL, &ahc, NULL,
   1326                              MHD_OPTION_ARRAY, opts,
   1327                              VARARG_CALLBACKS,
   1328                              MHD_OPTION_END);
   1329   }
   1330 }
   1331 
   1332 
   1333 /**
   1334  * The accept policy callback.  MHD_accept_connection() calls it with the
   1335  * peer address of every socket it accepts and closes the connection
   1336  * again when it answers MHD_NO, which is a code path (and a whole
   1337  * function, new_connection_close_()) that nothing else here reaches.
   1338  */
   1339 static enum MHD_Result
   1340 apc_cb (void *cls,
   1341         const struct sockaddr *addr,
   1342         socklen_t addrlen)
   1343 {
   1344   volatile size_t sink;
   1345 
   1346   (void) cls;
   1347   sink = (size_t) addrlen + ((NULL != addr) ? (size_t) addr->sa_family : 0u);
   1348   (void) sink;
   1349   return cfg.accept_policy_deny ? MHD_NO : MHD_YES;
   1350 }
   1351 
   1352 
   1353 /**
   1354  * Really connect to the daemon's listening socket.
   1355  *
   1356  * MHD_add_connection() bypasses accept(), so without this the whole
   1357  * accept path -- MHD_accept_connection(), the accept policy callback,
   1358  * the listen-socket branches of the three event loops -- is unreachable.
   1359  * The client end is given SO_LINGER {1, 0} so that close() sends a RST
   1360  * and neither side ends up in TIME_WAIT: at fuzzing rates the ephemeral
   1361  * port range would otherwise be exhausted within a couple of minutes.
   1362  *
   1363  * @param d the daemon, which must have a listening socket
   1364  * @param flags the flags it was started with, to pick the address family
   1365  * @return the connected socket, or -1
   1366  */
   1367 static int
   1368 connect_real (struct MHD_Daemon *d,
   1369               unsigned int flags)
   1370 {
   1371   const union MHD_DaemonInfo *di;
   1372   struct linger lg;
   1373   int s;
   1374   uint16_t port;
   1375 
   1376   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
   1377   if ( (NULL == di) ||
   1378        (0 == di->port) )
   1379     return -1;
   1380   port = (uint16_t) di->port;
   1381   prepare_sock_addrs ();
   1382 #ifdef AF_INET6
   1383   if (0 != (flags & MHD_USE_IPv6))
   1384   {
   1385     struct sockaddr_in6 to = bind6;
   1386 
   1387     to.sin6_port = htons (port);
   1388     s = socket (AF_INET6, SOCK_STREAM, 0);
   1389     if (0 > s)
   1390       return -1;
   1391     if (0 != connect (s, (const struct sockaddr *) &to, sizeof (to)))
   1392     {
   1393       (void) close (s);
   1394       return -1;
   1395     }
   1396   }
   1397   else
   1398 #endif
   1399   {
   1400     struct sockaddr_in to = bind4;
   1401 
   1402     to.sin_port = htons (port);
   1403     s = socket (AF_INET, SOCK_STREAM, 0);
   1404     if (0 > s)
   1405       return -1;
   1406     if (0 != connect (s, (const struct sockaddr *) &to, sizeof (to)))
   1407     {
   1408       (void) close (s);
   1409       return -1;
   1410     }
   1411   }
   1412   lg.l_onoff = 1;
   1413   lg.l_linger = 0;
   1414   (void) setsockopt (s, SOL_SOCKET, SO_LINGER, &lg, sizeof (lg));
   1415   stat_real_conns++;
   1416   return s;
   1417 }
   1418 
   1419 
   1420 /**
   1421  * Ask MHD_is_feature_supported() about one feature.  The function is a
   1422  * large switch in daemon.c that no other harness touches; the index
   1423  * comes off the input so that invalid values reach its default branch
   1424  * as well.
   1425  */
   1426 static void
   1427 query_feature (uint8_t sel)
   1428 {
   1429   volatile int sink;
   1430 
   1431   sink = (int) MHD_is_feature_supported ((enum MHD_FEATURE) (sel % 40u));
   1432   (void) sink;
   1433 }
   1434 
   1435 
   1436 /**
   1437  * Read everything MHD_get_daemon_info() offers.  All of it lives in
   1438  * daemon.c and none of it is reachable from the other harnesses.
   1439  */
   1440 static void
   1441 query_daemon_info (struct MHD_Daemon *d)
   1442 {
   1443   volatile unsigned int sink = 0;
   1444   const union MHD_DaemonInfo *di;
   1445 
   1446   sink += (unsigned int) (NULL != MHD_get_version ());
   1447   sink += MHD_get_version_bin ();
   1448 
   1449   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
   1450   if (NULL != di)
   1451     sink += di->num_connections;
   1452   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_FLAGS);
   1453   if (NULL != di)
   1454     sink += (unsigned int) di->flags;
   1455   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
   1456   if (NULL != di)
   1457     sink += di->port;
   1458   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
   1459   if (NULL != di)
   1460     sink += (unsigned int) (di->listen_fd + 1);
   1461   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_EPOLL_FD);
   1462   if (NULL != di)
   1463     sink += (unsigned int) (di->listen_fd + 1);
   1464   (void) sink;
   1465 }
   1466 
   1467 
   1468 /* ------------------------------------------------------------------ */
   1469 /* The fuzz target                                                     */
   1470 /* ------------------------------------------------------------------ */
   1471 
   1472 int
   1473 LLVMFuzzerTestOneInput (const uint8_t *data,
   1474                         size_t size)
   1475 {
   1476   struct MHD_Daemon *d;
   1477   struct MHD_OptionItem opts[MAX_OPTS];
   1478   unsigned int flags;
   1479   int sock = -1;
   1480   int rsock = -1;
   1481   size_t pos;
   1482   unsigned int nseg = 0;
   1483   unsigned int nconn = 1;
   1484   unsigned int cbsel;
   1485   MHD_socket quiesced = MHD_INVALID_SOCKET;
   1486 
   1487   /* Must happen before the first write() into the socketpair, and must
   1488      not be left to the built-in driver: fuzz_install_handlers() is
   1489      compiled out under -DFUZZ_NO_MAIN, which is exactly the build every
   1490      external fuzzing engine uses.  The call is idempotent.  See
   1491      fuzz_ignore_sigpipe() in fuzz_common.h for what happens without it. */
   1492   fuzz_ignore_sigpipe ();
   1493 
   1494   /* The sixteen configuration bytes are mandatory.  An input of exactly
   1495      that length is fine and starts a daemon with no traffic. */
   1496   if (size < CFG_BYTES)
   1497     return 0;
   1498 
   1499   memset (&cfg, 0, sizeof (cfg));
   1500   memset (pending_resume, 0, sizeof (pending_resume));
   1501   tearing_down = 0;
   1502 
   1503   flags = flags_from_input (data);
   1504   if (cfg.listen_sock)
   1505     flags &= ~((unsigned int) MHD_USE_NO_LISTEN_SOCKET);
   1506   else
   1507     flags |= MHD_USE_NO_LISTEN_SOCKET;
   1508   if (cfg.err_log)
   1509     flags |= MHD_USE_ERROR_LOG;
   1510   else
   1511     flags &= ~((unsigned int) MHD_USE_ERROR_LOG);
   1512 
   1513   cfg.uses_threads = (0 != (flags & (MHD_USE_INTERNAL_POLLING_THREAD
   1514                                      | MHD_USE_THREAD_PER_CONNECTION)));
   1515   if (cfg.uses_threads &&
   1516       (0 == (flags & MHD_USE_NO_THREAD_SAFETY)))
   1517   {
   1518     /* Without the inter-thread communication channel a worker only
   1519        notices a connection handed to it by MHD_add_connection() when its
   1520        own poll times out, so every threaded iteration would pay the full
   1521        wait.  MHD forces ITC on anyway whenever there is no listen
   1522        socket; this extends that to the daemons that have one. */
   1523     flags |= MHD_USE_ITC;
   1524   }
   1525 
   1526   cfg.loop_mode = (unsigned int) (data[12] & 0x03);
   1527   cfg.quiesce = (0 != (data[12] & 0x04));
   1528   if (cfg.quiesce &&
   1529       cfg.uses_threads &&
   1530       uses_epoll (flags) &&
   1531       (! quiesce_epoll_race_allowed ()))
   1532     cfg.quiesce = 0;
   1533   cfg.daemon_info = (0 != (data[12] & 0x08));
   1534   cfg.suspend_mode = (0 != (flags & SUSPEND_BIT))
   1535                      ? (int) ((data[12] >> 4) & 0x03)
   1536                      : 0;
   1537   if (3 == cfg.suspend_mode)
   1538     cfg.suspend_mode = 1;
   1539   cfg.nconn_max = 1u + (unsigned int) ((data[12] >> 6) & 0x03);
   1540   if (cfg.nconn_max > MAX_CONNECTIONS)
   1541     cfg.nconn_max = MAX_CONNECTIONS;
   1542 
   1543   cfg.resp_kind = (unsigned int) (data[13] & 0x03);
   1544   cfg.handler_no = (0 != (data[13] & 0x04));
   1545   cfg.conn_option = (0 != (data[13] & 0x08));
   1546   cfg.accept_policy = (0 != (data[13] & 0x10));
   1547   cfg.accept_policy_deny = (0 != (data[13] & 0x20));
   1548   /* One iteration in four of those that have a listening socket at all;
   1549      a real connect()/accept() pair is much more expensive than
   1550      MHD_add_connection() on a socketpair. */
   1551   cfg.real_connect = cfg.listen_sock && (0xC0 == (data[13] & 0xC0));
   1552 
   1553   (void) build_options (data, opts, flags);
   1554 
   1555   cbsel = (unsigned int) data[5];
   1556   /* MHD_USE_ERROR_LOG without MHD_OPTION_EXTERNAL_LOGGER sends every
   1557      message MHD produces to stderr through MHD_default_logger_, which
   1558      at fuzzing rates is tens of megabytes of noise.  The flag is far too
   1559      valuable to drop -- with it set, several hundred MHD_DLOG() call
   1560      sites in daemon.c become live -- so the logger is forced on instead
   1561      (bit 4 of the callback selector). */
   1562   if (cfg.err_log)
   1563     cbsel |= 0x10u;
   1564 
   1565   MHD_set_panic_func (&panic_cb, NULL);
   1566   d = start_daemon_variant (flags, opts, cbsel);
   1567   if (NULL == d)
   1568   {
   1569     /* Entirely normal: an unsupported flag combination, an option MHD
   1570        rejects, a bind() failure, ... */
   1571     stat_daemons_failed++;
   1572     return 0;
   1573   }
   1574   stat_daemons++;
   1575   if (cfg.uses_threads)
   1576     stat_threaded++;
   1577   if (! stats_registered)
   1578   {
   1579     stats_registered = 1;
   1580     (void) atexit (&print_stats);
   1581   }
   1582 
   1583   if (cfg.daemon_info)
   1584     query_daemon_info (d);
   1585   query_feature (data[15]);
   1586 
   1587   if (cfg.real_connect)
   1588   {
   1589     rsock = connect_real (d, flags);
   1590     if (0 <= rsock)
   1591     {
   1592       static const char req[] = "GET / HTTP/1.1\r\nHost: x\r\n\r\n";
   1593 
   1594       (void) send (rsock, req, sizeof (req) - 1, MSG_DONTWAIT);
   1595       if (cfg.uses_threads)
   1596         wait_threaded (rsock);
   1597       else
   1598         pump (d, rsock, PUMP_ROUNDS_LONG);
   1599     }
   1600   }
   1601 
   1602   (void) new_connection (d, &sock);
   1603 
   1604   pos = CFG_BYTES;
   1605   while ( (pos + 2 <= size) &&
   1606           (nseg < MAX_SEGMENTS) )
   1607   {
   1608     unsigned int hdr = (unsigned int) data[pos]
   1609                        | ((unsigned int) data[pos + 1] << 8);
   1610     unsigned int op = hdr >> 14;
   1611     size_t slen = (size_t) (hdr & 0x3FFF);
   1612 
   1613     pos += 2;
   1614     nseg++;
   1615     if (slen > size - pos)
   1616       slen = size - pos;
   1617 
   1618     if ( (3 == op) &&
   1619          (nconn < cfg.nconn_max) )
   1620     {
   1621       close_connection (d, &sock);
   1622       (void) new_connection (d, &sock);
   1623       nconn++;
   1624     }
   1625     if (0 != slen)
   1626       send_all (d, sock, data + pos, slen);
   1627     pos += slen;
   1628     if (cfg.uses_threads)
   1629       continue;                 /* the threaded shape drains at close */
   1630     pump (d, sock, (0 == op) ? PUMP_ROUNDS : PUMP_ROUNDS_LONG);
   1631   }
   1632 
   1633   close_connection (d, &sock);
   1634   pump (d, sock, 4);
   1635   if (0 <= rsock)
   1636   {
   1637     (void) shutdown (rsock, SHUT_WR);
   1638     if (cfg.uses_threads)
   1639       wait_threaded (rsock);
   1640     else
   1641       pump (d, rsock, 4);
   1642     (void) close (rsock);
   1643     rsock = -1;
   1644   }
   1645 
   1646   /* A connection left suspended makes MHD_stop_daemon() MHD_PANIC(), and
   1647      MHD_resume_connection() alone is not enough: it only raises a flag,
   1648      and the connection is taken off the daemon's suspended list by
   1649      MHD_run().  So flush and run until nothing is parked any more.
   1650      tearing_down keeps the handler from parking anything new, which is
   1651      what bounds this loop; the cap is only a backstop. */
   1652   tearing_down = 1;
   1653   if (! cfg.uses_threads)
   1654   {
   1655     unsigned int i;
   1656 
   1657     for (i = 0; i < MAX_CONNECTIONS + 2u; i++)
   1658     {
   1659       if (! pending_resume_flush ())
   1660         break;
   1661       (void) MHD_run (d);
   1662     }
   1663   }
   1664 
   1665   if (cfg.quiesce)
   1666   {
   1667     /* The returned socket belongs to the caller from here on, and with
   1668        internal threads it must not be closed before MHD_stop_daemon()
   1669        has joined them. */
   1670     quiesced = MHD_quiesce_daemon (d);
   1671   }
   1672   MHD_stop_daemon (d);
   1673   if (MHD_INVALID_SOCKET != quiesced)
   1674     (void) close ((int) quiesced);
   1675   return 0;
   1676 }
   1677 
   1678 
   1679 /* ------------------------------------------------------------------ */
   1680 /* Structure-aware generator                                           */
   1681 /* ------------------------------------------------------------------ */
   1682 
   1683 /* Defined unconditionally, exactly like the rest of the harness API:
   1684    only main() may live behind #ifndef FUZZ_NO_MAIN, and fuzz_common.h
   1685    already declares these three with FUZZ_UNUSED so that the libFuzzer
   1686    and AFL++ builds, which never call them, compile without a warning. */
   1687 
   1688 struct sbuf
   1689 {
   1690   uint8_t *p;
   1691   size_t len;
   1692   size_t cap;
   1693 };
   1694 
   1695 
   1696 static void
   1697 sb_raw (struct sbuf *b,
   1698         const void *s,
   1699         size_t n)
   1700 {
   1701   if (b->len + n > b->cap)
   1702     n = b->cap - b->len;
   1703   memcpy (b->p + b->len, s, n);
   1704   b->len += n;
   1705 }
   1706 
   1707 
   1708 static void
   1709 sb_str (struct sbuf *b,
   1710         const char *s)
   1711 {
   1712   sb_raw (b, s, strlen (s));
   1713 }
   1714 
   1715 
   1716 static void
   1717 sb_u64 (struct sbuf *b,
   1718         uint64_t v,
   1719         int hex)
   1720 {
   1721   char tmp[32];
   1722 
   1723   (void) snprintf (tmp, sizeof (tmp),
   1724                    hex ? "%llx" : "%llu",
   1725                    (unsigned long long) v);
   1726   sb_str (b, tmp);
   1727 }
   1728 
   1729 
   1730 static const char *const gen_methods[] = {
   1731   "GET", "POST", "HEAD", "PUT", "OPTIONS", "DELETE", "TRACE", "CONNECT",
   1732   "PATCH", "get", "BREW", ""
   1733 };
   1734 
   1735 static const char *const gen_targets[] = {
   1736   "/", "/a", "/a/b/c", "*", "http://x/a", "/%41%42", "/a?b=c&d",
   1737   "/very/long/path/that/does/not/fit/into/a/small/connection/memory/pool",
   1738   "/a?novalue", "//", "/.%2e/", "/\x01"
   1739 };
   1740 
   1741 static const char *const gen_versions[] = {
   1742   "HTTP/1.1", "HTTP/1.0", "HTTP/1.2", "HTTP/0.9", "HTTP/1", ""
   1743 };
   1744 
   1745 static const char *const gen_hdr_names[] = {
   1746   "Host", "Connection", "Accept", "User-Agent", "Cookie", "Expect",
   1747   "Content-Type", "X-Fuzz", "Upgrade", "Accept-Encoding", "Range",
   1748   "If-Modified-Since"
   1749 };
   1750 
   1751 static const char *const gen_hdr_values[] = {
   1752   "x", "keep-alive", "close", "*/*", "a=b; c=d", "100-continue",
   1753   "text/plain", "1", "fuzz-protocol", "gzip", "bytes=0-1", "chunked"
   1754 };
   1755 
   1756 
   1757 /**
   1758  * Emit one HTTP request into @a b.
   1759  *
   1760  * The shapes are deliberately unambitious -- the request parser is
   1761  * fuzz_request's subject, not this harness's.  What matters here is that
   1762  * the bytes form something MHD will actually take through its state
   1763  * machine under whatever daemon configuration the configuration bytes
   1764  * describe, so that the option handling is exercised against a live
   1765  * connection rather than against a connection MHD drops on the first
   1766  * byte.
   1767  */
   1768 static void
   1769 gen_request (struct fuzz_rng *rng,
   1770              struct sbuf *b,
   1771              unsigned int shape)
   1772 {
   1773   unsigned int nhdr;
   1774   unsigned int i;
   1775 
   1776   switch (shape % 10)
   1777   {
   1778   case 9:
   1779     /* Not HTTP at all: MHD has to reject it, which is its own path. */
   1780     for (i = 0; i < 24; i++)
   1781     {
   1782       uint8_t c = fuzz_byte (rng);
   1783 
   1784       sb_raw (b, &c, 1);
   1785     }
   1786     return;
   1787   case 6:
   1788     /* Two pipelined requests on one connection. */
   1789     sb_str (b, "GET /a HTTP/1.1\r\nHost: x\r\n\r\n");
   1790     sb_str (b, "GET /b HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n");
   1791     return;
   1792   default:
   1793     break;
   1794   }
   1795 
   1796   sb_str (b, gen_methods[fuzz_below (rng, (uint32_t) (sizeof (gen_methods)
   1797                                                       / sizeof (gen_methods[0]
   1798                                                                 )))]);
   1799   sb_str (b, " ");
   1800   sb_str (b, gen_targets[fuzz_below (rng, (uint32_t) (sizeof (gen_targets)
   1801                                                       / sizeof (gen_targets[0]
   1802                                                                 )))]);
   1803   sb_str (b, " ");
   1804   sb_str (b, gen_versions[fuzz_below (rng,
   1805                                       (uint32_t) (sizeof (gen_versions)
   1806                                                   / sizeof (gen_versions[0])))
   1807           ]);
   1808   sb_str (b, "\r\n");
   1809 
   1810   nhdr = (5 == (shape % 10)) ? (8 + fuzz_below (rng, 24)) : fuzz_below (rng, 5);
   1811   for (i = 0; i < nhdr; i++)
   1812   {
   1813     sb_str (b, gen_hdr_names[fuzz_below (rng,
   1814                                          (uint32_t) (sizeof (gen_hdr_names)
   1815                                                      / sizeof (gen_hdr_names[0]
   1816                                                                )))]);
   1817     sb_str (b, ": ");
   1818     sb_str (b, gen_hdr_values[fuzz_below (rng,
   1819                                           (uint32_t) (sizeof (gen_hdr_values)
   1820                                                       / sizeof (gen_hdr_values[
   1821                                                                   0])))]);
   1822     sb_str (b, "\r\n");
   1823   }
   1824 
   1825   switch (shape % 10)
   1826   {
   1827   case 2:                      /* Content-Length body */
   1828     {
   1829       uint32_t n = fuzz_below (rng, 64);
   1830 
   1831       sb_str (b, "Content-Length: ");
   1832       sb_u64 (b, n, 0);
   1833       sb_str (b, "\r\n\r\n");
   1834       for (i = 0; i < n; i++)
   1835         sb_str (b, "A");
   1836       break;
   1837     }
   1838   case 3:                      /* chunked body */
   1839     {
   1840       unsigned int nch = 1 + fuzz_below (rng, 3);
   1841 
   1842       sb_str (b, "Transfer-Encoding: chunked\r\n\r\n");
   1843       for (i = 0; i < nch; i++)
   1844       {
   1845         uint32_t n = 1 + fuzz_below (rng, 16);
   1846         uint32_t k;
   1847 
   1848         sb_u64 (b, n, 1);
   1849         sb_str (b, "\r\n");
   1850         for (k = 0; k < n; k++)
   1851           sb_str (b, "B");
   1852         sb_str (b, "\r\n");
   1853       }
   1854       sb_str (b, "0\r\n\r\n");
   1855       break;
   1856     }
   1857   case 4:                      /* expect 100-continue */
   1858     sb_str (b, "Expect: 100-continue\r\nContent-Length: 4\r\n\r\nabcd");
   1859     break;
   1860   case 7:                      /* upgrade request */
   1861     sb_str (b, "Connection: Upgrade\r\nUpgrade: fuzz-protocol\r\n\r\n");
   1862     break;
   1863   case 8:                      /* truncated: MHD keeps waiting for more */
   1864     sb_str (b, "X-Trunc: ");
   1865     break;
   1866   default:
   1867     sb_str (b, "\r\n");
   1868     break;
   1869   }
   1870 }
   1871 
   1872 
   1873 /**
   1874  * Serialise @a body into the segment stream understood by
   1875  * LLVMFuzzerTestOneInput().
   1876  */
   1877 static void
   1878 emit_segments (struct fuzz_rng *rng,
   1879                struct sbuf *out,
   1880                const uint8_t *body,
   1881                size_t body_len,
   1882                int new_conn_first)
   1883 {
   1884   size_t off = 0;
   1885   int first = 1;
   1886 
   1887   while (off < body_len)
   1888   {
   1889     size_t chunk;
   1890     unsigned int op;
   1891     uint8_t hdr[2];
   1892     unsigned int hv;
   1893 
   1894     switch (fuzz_below (rng, 5))
   1895     {
   1896     case 0:
   1897       chunk = 1;
   1898       break;
   1899     case 1:
   1900       chunk = 2 + fuzz_below (rng, 8);
   1901       break;
   1902     default:
   1903       chunk = body_len - off;
   1904       break;
   1905     }
   1906     if (chunk > body_len - off)
   1907       chunk = body_len - off;
   1908     if (chunk > 0x3FFF)
   1909       chunk = 0x3FFF;
   1910     op = (first && new_conn_first) ? 3u : (fuzz_chance (rng, 5) ? 2u : 0u);
   1911     hv = (op << 14) | (unsigned int) chunk;
   1912     hdr[0] = (uint8_t) (hv & 0xFF);
   1913     hdr[1] = (uint8_t) (hv >> 8);
   1914     if (out->len + 2 + chunk > out->cap)
   1915       return;
   1916     sb_raw (out, hdr, 2);
   1917     sb_raw (out, body + off, chunk);
   1918     off += chunk;
   1919     first = 0;
   1920   }
   1921 }
   1922 
   1923 
   1924 /**
   1925  * The generator.
   1926  *
   1927  * Purely random configuration bytes are already useful for this harness
   1928  * -- unlike an HTTP request, an option array has no grammar to get wrong
   1929  * -- but two things still need help.  Byte 0 is biased into the range of
   1930  * mode_tbl[] so that most iterations get a daemon that actually starts,
   1931  * and the tail of the input has to look like HTTP, or MHD closes every
   1932  * connection before any of the configured behaviour has a chance to
   1933  * matter.
   1934  */
   1935 static size_t
   1936 fuzz_generate (struct fuzz_rng *rng,
   1937                uint8_t *buf,
   1938                size_t cap)
   1939 {
   1940   struct sbuf out;
   1941   uint8_t cfg_bytes[CFG_BYTES];
   1942   uint8_t req[GEN_BUF_SIZE];
   1943   struct sbuf rb;
   1944   unsigned int nreq;
   1945   unsigned int i;
   1946 
   1947   out.p = buf;
   1948   out.len = 0;
   1949   out.cap = cap;
   1950 
   1951   for (i = 0; i < CFG_BYTES; i++)
   1952     cfg_bytes[i] = fuzz_byte (rng);
   1953 
   1954   /* Byte 0 selects the daemon shape; keep it inside the table so that
   1955      the value is not folded by the modulo in an uneven way. */
   1956   cfg_bytes[0] = (uint8_t) fuzz_below (rng, (uint32_t) MODE_COUNT);
   1957   /* The raw flag escape is 1 in 4 of the byte-2 values, which is far too
   1958      often: those daemons mostly fail to start and never reach the option
   1959      handling.  Clear the escape unless it is explicitly rolled. */
   1960   if (! fuzz_chance (rng, 10))
   1961     cfg_bytes[2] &= (uint8_t) ~0xC0u;
   1962   else
   1963     cfg_bytes[2] |= (uint8_t) 0xC0u;
   1964   /* Likewise the deliberately invalid option number: useful, but every
   1965      input carrying it ends in MHD_start_daemon() == NULL. */
   1966   if (! fuzz_chance (rng, 20))
   1967     cfg_bytes[14] &= (uint8_t) ~0x40u;
   1968 
   1969   sb_raw (&out, cfg_bytes, CFG_BYTES);
   1970 
   1971   nreq = 1u + (fuzz_chance (rng, 4) ? 1u : 0u);
   1972   for (i = 0; i < nreq; i++)
   1973   {
   1974     rb.p = req;
   1975     rb.len = 0;
   1976     rb.cap = sizeof (req);
   1977     gen_request (rng, &rb, fuzz_below (rng, 10));
   1978     emit_segments (rng, &out, req, rb.len,
   1979                    (0 != i) || fuzz_chance (rng, 6));
   1980   }
   1981   return out.len;
   1982 }
   1983 
   1984 
   1985 /* ------------------------------------------------------------------ */
   1986 /* Built-in seed corpus                                                */
   1987 /* ------------------------------------------------------------------ */
   1988 
   1989 /**
   1990  * A seed is sixteen configuration bytes plus one request, rendered into
   1991  * the wire format at run time so that segment lengths never have to be
   1992  * spelled out by hand.
   1993  *
   1994  * Every seed turns on exactly one area, so that a corpus minimiser keeps
   1995  * them distinguishable, and the configuration bytes of a seed that does
   1996  * not care about an area are zero -- which is the plainest setting:
   1997  * external polling with select(), no listen socket, no options at all,
   1998  * one connection, MHD_run() as the event loop.
   1999  */
   2000 struct seed_def
   2001 {
   2002   const char *name;
   2003   unsigned char cfg[CFG_BYTES];
   2004   const char *req;
   2005 };
   2006 
   2007 /* Byte positions inside seed_def::cfg, for readability. */
   2008 #define C_MODE 0
   2009 #define C_FLAGA 1
   2010 #define C_FLAGB 2
   2011 #define C_OPTA 3
   2012 #define C_OPTB 4
   2013 #define C_OPTC 5
   2014 #define C_VAL_MEM 6
   2015 #define C_VAL_CONN 7
   2016 #define C_VAL_THR 8
   2017 #define C_VAL_DAUTH 9
   2018 #define C_VAL_DISC 10
   2019 #define C_VAL_SOCK 11
   2020 #define C_DRIVE 12
   2021 #define C_HANDLER 13
   2022 #define C_OPTD 14
   2023 #define C_SPARE 15
   2024 
   2025 #define REQ_PLAIN "GET /a HTTP/1.1\r\nHost: x\r\n\r\n"
   2026 #define REQ_CLOSE "GET /a HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n"
   2027 #define REQ_POST \
   2028         "POST /a HTTP/1.1\r\nHost: x\r\nContent-Length: 4\r\n\r\nabcd"
   2029 #define REQ_CHUNKED \
   2030         "POST /a HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n" \
   2031         "\r\n3\r\nabc\r\n0\r\n\r\n"
   2032 
   2033 static const struct seed_def seeds[] = {
   2034   /* ---- the event loops, all external ---- */
   2035   { "plain-external-run",
   2036     { 0 }, REQ_PLAIN },
   2037   { "external-fdset2",
   2038     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 | 0x08, 0, 0, 0 },
   2039     REQ_PLAIN },
   2040   { "external-run-wait",
   2041     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0 },
   2042     REQ_PLAIN },
   2043   { "external-fdset-v1",
   2044     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0, 0, 0 },
   2045     REQ_PLAIN },
   2046   { "external-epoll",
   2047     { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2048     REQ_PLAIN },
   2049   { "external-auto",
   2050     { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2051     REQ_PLAIN },
   2052 
   2053   /* ---- the daemon shapes that run their own threads ---- */
   2054   { "internal-thread-select",
   2055     { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2056     REQ_CLOSE },
   2057   { "internal-thread-poll",
   2058     { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2059     REQ_CLOSE },
   2060   { "internal-thread-epoll",
   2061     { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2062     REQ_CLOSE },
   2063   { "thread-per-connection",
   2064     { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2065     REQ_CLOSE },
   2066   { "thread-per-connection-poll",
   2067     { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2068     REQ_CLOSE },
   2069   /* A thread pool needs MHD_OPTION_THREAD_POOL_SIZE (option mask A bit
   2070      5) on top of an internal polling thread, and is rejected outright
   2071      with thread-per-connection. */
   2072   { "thread-pool",
   2073     { 18, 0, 0, 0x20, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0, 0, 0 },
   2074     REQ_CLOSE },
   2075   { "thread-pool-epoll-stack",
   2076     { 20, 0, 0, 0x20 | 0x40, 0, 0, 0, 0, 0x10 | 0x20, 0, 0, 0, 0, 0, 0, 0 },
   2077     REQ_CLOSE },
   2078 
   2079   /* ---- a real listening socket ---- */
   2080   { "listen-socket",
   2081     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2082     REQ_PLAIN },
   2083   { "listen-socket-reuse-backlog",
   2084     { 0, 0, 0x01, 0x80, 0x01, 0, 0, 0, 0, 0, 0, 0x01 | 0x06, 0, 0, 0, 0 },
   2085     REQ_PLAIN },
   2086   { "listen-socket-sockaddr",
   2087     { 0, 0, 0x01, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2088     REQ_PLAIN },
   2089   { "listen-socket-ipv6-dual",
   2090     { 0, 0, 0x01 | 0x02 | 0x04, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2091     REQ_PLAIN },
   2092   { "listen-socket-quiesce",
   2093     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04 | 0x08, 0, 0, 0 },
   2094     REQ_PLAIN },
   2095   { "listen-socket-internal-thread",
   2096     { 18, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0, 0, 0 },
   2097     REQ_CLOSE },
   2098 
   2099   /* ---- the accept() path: a real client on the listening socket ----
   2100      Byte 13 bit 0x40|0x80 asks for the connect(), bit 0x10 installs the
   2101      accept policy callback and bit 0x20 makes it say no.  Without these
   2102      MHD_accept_connection() and the listen-socket branches of the three
   2103      event loops are never entered at all: MHD_add_connection() bypasses
   2104      accept() completely. */
   2105   { "real-connect",
   2106     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2107     REQ_PLAIN },
   2108   { "real-connect-accept-policy",
   2109     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0 | 0x10, 0, 0 },
   2110     REQ_PLAIN },
   2111   { "real-connect-accept-denied",
   2112     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0 | 0x10 | 0x20, 0, 0 },
   2113     REQ_PLAIN },
   2114   { "real-connect-internal-thread",
   2115     { 18, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2116     REQ_CLOSE },
   2117   { "real-connect-external-epoll",
   2118     { 12, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2119     REQ_PLAIN },
   2120 
   2121   /* ---- the memory options ---- */
   2122   { "tiny-pool",
   2123     { 0, 0, 0, 0x01 | 0x02, 0, 0, 0x01 | 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2124     REQ_PLAIN },
   2125   { "big-pool-big-increment",
   2126     { 0, 0, 0, 0x01 | 0x02, 0, 0, 0x0C | 0x60, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2127     REQ_POST },
   2128 
   2129   /* ---- the connection limits ---- */
   2130   { "connection-limit-one",
   2131     { 0, 0, 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0xC0, 0, 0, 0 },
   2132     REQ_PLAIN },
   2133   { "per-ip-limit-one",
   2134     { 0, 0, 0, 0x08, 0, 0, 0, 0x10, 0, 0, 0, 0, 0xC0, 0, 0, 0 },
   2135     REQ_PLAIN },
   2136   { "connection-limit-zero",
   2137     { 0, 0, 0, 0x04, 0, 0, 0, 0x00, 0, 0, 0, 0, 0, 0, 0, 0 },
   2138     REQ_PLAIN },
   2139   { "connection-timeout",
   2140     { 0, 0, 0, 0x10, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0 },
   2141     REQ_PLAIN },
   2142 
   2143   /* ---- parsing discipline and insanity ---- */
   2144   { "discipline-lowest",
   2145     { 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0 },
   2146     "GET /a HTTP/1.1\r\n Host: x\r\n\r\n" },
   2147   { "discipline-highest-pedantic",
   2148     { 0, 0x01, 0, 0, 0x10, 0, 0, 0, 0, 0, 0x05, 0, 0, 0, 0, 0 },
   2149     REQ_PLAIN },
   2150   { "strict-for-client",
   2151     { 0, 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0 },
   2152     REQ_PLAIN },
   2153   { "server-insanity",
   2154     { 0, 0, 0, 0, 0x04, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0 },
   2155     REQ_PLAIN },
   2156   { "bin-zero-in-uri-path",
   2157     { 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0 },
   2158     "GET /a%00b HTTP/1.1\r\nHost: x\r\n\r\n" },
   2159   { "app-fd-setsize",
   2160     { 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0x00, 0x01, 0, 0, 0 },
   2161     REQ_PLAIN },
   2162 
   2163   /* ---- the callbacks ---- */
   2164   { "notify-completed",
   2165     { 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2166     REQ_PLAIN },
   2167   { "notify-connection",
   2168     { 0, 0, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2169     REQ_PLAIN },
   2170   { "uri-log-callback",
   2171     { 0, 0, 0, 0, 0, 0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2172     "GET /a?q=%41 HTTP/1.1\r\nHost: x\r\n\r\n" },
   2173   { "external-logger",
   2174     { 0, 0x40, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2175     REQ_PLAIN },
   2176   { "unescape-callback",
   2177     { 0, 0, 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2178     "GET /%41%42?a=%43 HTTP/1.1\r\nHost: x\r\n\r\n" },
   2179   { "all-callbacks-error-log",
   2180     { 0, 0x40, 0, 0, 0, 0x01 | 0x02 | 0x04 | 0x08 | 0x10,
   2181       0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2182     REQ_PLAIN },
   2183 
   2184   /* ---- digest-auth related options ---- */
   2185   { "digest-random",
   2186     { 0, 0, 0, 0, 0x02, 0x20, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0 },
   2187     REQ_PLAIN },
   2188   { "digest-random-copy",
   2189     { 0, 0, 0, 0, 0x02, 0x20 | 0x40, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0 },
   2190     REQ_PLAIN },
   2191   { "digest-nonce-bind-and-defaults",
   2192     { 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0x3C, 0, 0, 0, 0,
   2193       0x01 | 0x02 | 0x04, 0x11 },
   2194     REQ_PLAIN },
   2195 
   2196   /* ---- suspend / resume ---- */
   2197   { "suspend-immediate",
   2198     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 },
   2199     REQ_PLAIN },
   2200   { "suspend-deferred",
   2201     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0 },
   2202     REQ_PLAIN },
   2203   { "suspend-deferred-two-connections",
   2204     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x20 | 0x40, 0, 0, 0 },
   2205     REQ_PLAIN },
   2206 
   2207   /* ---- the remaining flag bits ---- */
   2208   { "turbo-itc-suppress-date",
   2209     { 0, 0x02 | 0x10 | 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2210     REQ_PLAIN },
   2211   { "allow-upgrade",
   2212     { 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2213     "GET / HTTP/1.1\r\nHost: x\r\nConnection: Upgrade\r\n"
   2214     "Upgrade: fuzz-protocol\r\n\r\n" },
   2215   { "no-thread-safety",
   2216     { 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2217     REQ_PLAIN },
   2218   { "tcp-fastopen-listen",
   2219     { 0, 0, 0x01 | 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0x08, 0 },
   2220     REQ_PLAIN },
   2221   { "sigpipe-handled-by-app",
   2222     { 0, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2223     REQ_PLAIN },
   2224   { "listen-socket-option-invalid-fd",
   2225     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0 },
   2226     REQ_PLAIN },
   2227 
   2228   /* ---- inputs whose daemon must not start ---- */
   2229   /* Raw flag escape: MHD_USE_POLL together with MHD_USE_EPOLL. */
   2230   { "raw-flags-poll-and-epoll",
   2231     { 0, 0x40, 0xC0 | 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2232     REQ_PLAIN },
   2233   /* Raw flag escape: MHD_USE_EPOLL with MHD_USE_THREAD_PER_CONNECTION. */
   2234   { "raw-flags-epoll-thread-per-conn",
   2235     { 0, 0x04 | 0x08, 0xC0 | 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2236     REQ_PLAIN },
   2237   /* An option number MHD does not know. */
   2238   { "invalid-option-number",
   2239     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0 },
   2240     REQ_PLAIN },
   2241   /* MHD_OPTION_THREAD_POOL_SIZE without an internal polling thread. */
   2242   { "thread-pool-without-threads",
   2243     { 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2244     REQ_PLAIN },
   2245 
   2246   /* ---- the handler behaviours ---- */
   2247   { "handler-returns-no",
   2248     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0, 0 },
   2249     REQ_PLAIN },
   2250   { "empty-and-copied-responses",
   2251     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 | 0x08, 0, 0 },
   2252     REQ_CHUNKED },
   2253   { "error-response",
   2254     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0, 0 },
   2255     REQ_POST },
   2256 
   2257   /* ---- everything at once ---- */
   2258   { "kitchen-sink-external",
   2259     { 0, 0x02 | 0x04 | 0x10 | 0x20 | 0x40, 0x01,
   2260       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x80,
   2261       0x02 | 0x10 | 0x20 | 0x40 | 0x80,
   2262       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20,
   2263       0x63, 0x45, 0x21, 0x13, 0x02, 0x0A,
   2264       0x01 | 0x04 | 0x08 | 0x20, 0x08, 0x01 | 0x02 | 0x04 | 0x10, 0x33 },
   2265     REQ_POST },
   2266   { "kitchen-sink-thread-pool",
   2267     { 18, 0x02 | 0x10 | 0x20 | 0x40, 0x01,
   2268       0x01 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
   2269       0x01 | 0x02 | 0x80,
   2270       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20,
   2271       0x03, 0x46, 0x39, 0x02, 0x00, 0x0A,
   2272       0x04 | 0x08, 0x00, 0x01 | 0x08, 0x22 },
   2273     REQ_CLOSE }
   2274 };
   2275 
   2276 static uint8_t seed_render_buf[1024];
   2277 
   2278 
   2279 static size_t
   2280 fuzz_seed_count (void)
   2281 {
   2282   return sizeof (seeds) / sizeof (seeds[0]);
   2283 }
   2284 
   2285 
   2286 static const uint8_t *
   2287 fuzz_seed_get (size_t idx,
   2288                size_t *len)
   2289 {
   2290   const struct seed_def *sd = &seeds[idx];
   2291   struct sbuf b;
   2292 
   2293   b.p = seed_render_buf;
   2294   b.len = 0;
   2295   b.cap = sizeof (seed_render_buf);
   2296   sb_raw (&b, sd->cfg, CFG_BYTES);
   2297   if (NULL != sd->req)
   2298   {
   2299     size_t n = strlen (sd->req);
   2300     unsigned int hv;
   2301     uint8_t hdr[2];
   2302 
   2303     if (n > 0x3FFF)
   2304       n = 0x3FFF;
   2305     hv = (0u << 14) | (unsigned int) n;
   2306     hdr[0] = (uint8_t) (hv & 0xFF);
   2307     hdr[1] = (uint8_t) (hv >> 8);
   2308     sb_raw (&b, hdr, 2);
   2309     sb_raw (&b, sd->req, n);
   2310   }
   2311   *len = b.len;
   2312   return seed_render_buf;
   2313 }