libmicrohttpd

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

fuzz_options.c (76668B)


      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 answering MHD_NO makes
   1336  * new_connection_prepare_() close the socket and drop the IP-limit entry
   1337  * before any connection object exists -- a path nothing else here
   1338  * reaches.  (It does *not* reach new_connection_close_(): that one is
   1339  * only called from close_all_connections(), for connections queued by
   1340  * MHD_add_connection() and never started.  See the byte 3 bit 4
   1341  * scenario in fuzz_eventloop.c.)
   1342  */
   1343 static enum MHD_Result
   1344 apc_cb (void *cls,
   1345         const struct sockaddr *addr,
   1346         socklen_t addrlen)
   1347 {
   1348   volatile size_t sink;
   1349 
   1350   (void) cls;
   1351   sink = (size_t) addrlen + ((NULL != addr) ? (size_t) addr->sa_family : 0u);
   1352   (void) sink;
   1353   return cfg.accept_policy_deny ? MHD_NO : MHD_YES;
   1354 }
   1355 
   1356 
   1357 /**
   1358  * Really connect to the daemon's listening socket.
   1359  *
   1360  * MHD_add_connection() bypasses accept(), so without this the whole
   1361  * accept path -- MHD_accept_connection(), the accept policy callback,
   1362  * the listen-socket branches of the three event loops -- is unreachable.
   1363  * The client end is given SO_LINGER {1, 0} so that close() sends a RST
   1364  * and neither side ends up in TIME_WAIT: at fuzzing rates the ephemeral
   1365  * port range would otherwise be exhausted within a couple of minutes.
   1366  *
   1367  * @param d the daemon, which must have a listening socket
   1368  * @param flags the flags it was started with, to pick the address family
   1369  * @return the connected socket, or -1
   1370  */
   1371 static int
   1372 connect_real (struct MHD_Daemon *d,
   1373               unsigned int flags)
   1374 {
   1375   const union MHD_DaemonInfo *di;
   1376   struct linger lg;
   1377   int s;
   1378   uint16_t port;
   1379 
   1380   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
   1381   if ( (NULL == di) ||
   1382        (0 == di->port) )
   1383     return -1;
   1384   port = (uint16_t) di->port;
   1385   prepare_sock_addrs ();
   1386 #ifdef AF_INET6
   1387   if (0 != (flags & MHD_USE_IPv6))
   1388   {
   1389     struct sockaddr_in6 to = bind6;
   1390 
   1391     to.sin6_port = htons (port);
   1392     s = socket (AF_INET6, SOCK_STREAM, 0);
   1393     if (0 > s)
   1394       return -1;
   1395     if (0 != connect (s, (const struct sockaddr *) &to, sizeof (to)))
   1396     {
   1397       (void) close (s);
   1398       return -1;
   1399     }
   1400   }
   1401   else
   1402 #endif
   1403   {
   1404     struct sockaddr_in to = bind4;
   1405 
   1406     to.sin_port = htons (port);
   1407     s = socket (AF_INET, SOCK_STREAM, 0);
   1408     if (0 > s)
   1409       return -1;
   1410     if (0 != connect (s, (const struct sockaddr *) &to, sizeof (to)))
   1411     {
   1412       (void) close (s);
   1413       return -1;
   1414     }
   1415   }
   1416   lg.l_onoff = 1;
   1417   lg.l_linger = 0;
   1418   (void) setsockopt (s, SOL_SOCKET, SO_LINGER, &lg, sizeof (lg));
   1419   stat_real_conns++;
   1420   return s;
   1421 }
   1422 
   1423 
   1424 /**
   1425  * Ask MHD_is_feature_supported() about one feature.  The function is a
   1426  * large switch in daemon.c that no other harness touches; the index
   1427  * comes off the input so that invalid values reach its default branch
   1428  * as well.
   1429  */
   1430 static void
   1431 query_feature (uint8_t sel)
   1432 {
   1433   volatile int sink;
   1434 
   1435   sink = (int) MHD_is_feature_supported ((enum MHD_FEATURE) (sel % 40u));
   1436   (void) sink;
   1437 }
   1438 
   1439 
   1440 /**
   1441  * Read everything MHD_get_daemon_info() offers.  All of it lives in
   1442  * daemon.c and none of it is reachable from the other harnesses.
   1443  */
   1444 static void
   1445 query_daemon_info (struct MHD_Daemon *d)
   1446 {
   1447   volatile unsigned int sink = 0;
   1448   const union MHD_DaemonInfo *di;
   1449 
   1450   sink += (unsigned int) (NULL != MHD_get_version ());
   1451   sink += MHD_get_version_bin ();
   1452 
   1453   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_CURRENT_CONNECTIONS);
   1454   if (NULL != di)
   1455     sink += di->num_connections;
   1456   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_FLAGS);
   1457   if (NULL != di)
   1458     sink += (unsigned int) di->flags;
   1459   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
   1460   if (NULL != di)
   1461     sink += di->port;
   1462   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
   1463   if (NULL != di)
   1464     sink += (unsigned int) (di->listen_fd + 1);
   1465   di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_EPOLL_FD);
   1466   if (NULL != di)
   1467     sink += (unsigned int) (di->listen_fd + 1);
   1468   (void) sink;
   1469 }
   1470 
   1471 
   1472 /* ------------------------------------------------------------------ */
   1473 /* The fuzz target                                                     */
   1474 /* ------------------------------------------------------------------ */
   1475 
   1476 int
   1477 LLVMFuzzerTestOneInput (const uint8_t *data,
   1478                         size_t size)
   1479 {
   1480   struct MHD_Daemon *d;
   1481   struct MHD_OptionItem opts[MAX_OPTS];
   1482   unsigned int flags;
   1483   int sock = -1;
   1484   int rsock = -1;
   1485   size_t pos;
   1486   unsigned int nseg = 0;
   1487   unsigned int nconn = 1;
   1488   unsigned int cbsel;
   1489   MHD_socket quiesced = MHD_INVALID_SOCKET;
   1490 
   1491   /* Must happen before the first write() into the socketpair, and must
   1492      not be left to the built-in driver: fuzz_install_handlers() is
   1493      compiled out under -DFUZZ_NO_MAIN, which is exactly the build every
   1494      external fuzzing engine uses.  The call is idempotent.  See
   1495      fuzz_ignore_sigpipe() in fuzz_common.h for what happens without it. */
   1496   fuzz_ignore_sigpipe ();
   1497 
   1498   /* The sixteen configuration bytes are mandatory.  An input of exactly
   1499      that length is fine and starts a daemon with no traffic. */
   1500   if (size < CFG_BYTES)
   1501     return 0;
   1502 
   1503   memset (&cfg, 0, sizeof (cfg));
   1504   memset (pending_resume, 0, sizeof (pending_resume));
   1505   tearing_down = 0;
   1506 
   1507   flags = flags_from_input (data);
   1508   if (cfg.listen_sock)
   1509     flags &= ~((unsigned int) MHD_USE_NO_LISTEN_SOCKET);
   1510   else
   1511     flags |= MHD_USE_NO_LISTEN_SOCKET;
   1512   if (cfg.err_log)
   1513     flags |= MHD_USE_ERROR_LOG;
   1514   else
   1515     flags &= ~((unsigned int) MHD_USE_ERROR_LOG);
   1516 
   1517   cfg.uses_threads = (0 != (flags & (MHD_USE_INTERNAL_POLLING_THREAD
   1518                                      | MHD_USE_THREAD_PER_CONNECTION)));
   1519   if (cfg.uses_threads &&
   1520       (0 == (flags & MHD_USE_NO_THREAD_SAFETY)))
   1521   {
   1522     /* Without the inter-thread communication channel a worker only
   1523        notices a connection handed to it by MHD_add_connection() when its
   1524        own poll times out, so every threaded iteration would pay the full
   1525        wait.  MHD forces ITC on anyway whenever there is no listen
   1526        socket; this extends that to the daemons that have one. */
   1527     flags |= MHD_USE_ITC;
   1528   }
   1529 
   1530   cfg.loop_mode = (unsigned int) (data[12] & 0x03);
   1531   cfg.quiesce = (0 != (data[12] & 0x04));
   1532   if (cfg.quiesce &&
   1533       cfg.uses_threads &&
   1534       uses_epoll (flags) &&
   1535       (! quiesce_epoll_race_allowed ()))
   1536     cfg.quiesce = 0;
   1537   cfg.daemon_info = (0 != (data[12] & 0x08));
   1538   cfg.suspend_mode = (0 != (flags & SUSPEND_BIT))
   1539                      ? (int) ((data[12] >> 4) & 0x03)
   1540                      : 0;
   1541   if (3 == cfg.suspend_mode)
   1542     cfg.suspend_mode = 1;
   1543   cfg.nconn_max = 1u + (unsigned int) ((data[12] >> 6) & 0x03);
   1544   if (cfg.nconn_max > MAX_CONNECTIONS)
   1545     cfg.nconn_max = MAX_CONNECTIONS;
   1546 
   1547   cfg.resp_kind = (unsigned int) (data[13] & 0x03);
   1548   cfg.handler_no = (0 != (data[13] & 0x04));
   1549   cfg.conn_option = (0 != (data[13] & 0x08));
   1550   cfg.accept_policy = (0 != (data[13] & 0x10));
   1551   cfg.accept_policy_deny = (0 != (data[13] & 0x20));
   1552   /* One iteration in four of those that have a listening socket at all;
   1553      a real connect()/accept() pair is much more expensive than
   1554      MHD_add_connection() on a socketpair. */
   1555   cfg.real_connect = cfg.listen_sock && (0xC0 == (data[13] & 0xC0));
   1556 
   1557   (void) build_options (data, opts, flags);
   1558 
   1559   cbsel = (unsigned int) data[5];
   1560   /* MHD_USE_ERROR_LOG without MHD_OPTION_EXTERNAL_LOGGER sends every
   1561      message MHD produces to stderr through MHD_default_logger_, which
   1562      at fuzzing rates is tens of megabytes of noise.  The flag is far too
   1563      valuable to drop -- with it set, several hundred MHD_DLOG() call
   1564      sites in daemon.c become live -- so the logger is forced on instead
   1565      (bit 4 of the callback selector). */
   1566   if (cfg.err_log)
   1567     cbsel |= 0x10u;
   1568 
   1569   MHD_set_panic_func (&panic_cb, NULL);
   1570   d = start_daemon_variant (flags, opts, cbsel);
   1571   if (NULL == d)
   1572   {
   1573     /* Entirely normal: an unsupported flag combination, an option MHD
   1574        rejects, a bind() failure, ... */
   1575     stat_daemons_failed++;
   1576     return 0;
   1577   }
   1578   stat_daemons++;
   1579   if (cfg.uses_threads)
   1580     stat_threaded++;
   1581   if (! stats_registered)
   1582   {
   1583     stats_registered = 1;
   1584     (void) atexit (&print_stats);
   1585   }
   1586 
   1587   if (cfg.daemon_info)
   1588     query_daemon_info (d);
   1589   query_feature (data[15]);
   1590 
   1591   if (cfg.real_connect)
   1592   {
   1593     rsock = connect_real (d, flags);
   1594     if (0 <= rsock)
   1595     {
   1596       static const char req[] = "GET / HTTP/1.1\r\nHost: x\r\n\r\n";
   1597 
   1598       (void) send (rsock, req, sizeof (req) - 1, MSG_DONTWAIT);
   1599       if (cfg.uses_threads)
   1600         wait_threaded (rsock);
   1601       else
   1602         pump (d, rsock, PUMP_ROUNDS_LONG);
   1603     }
   1604   }
   1605 
   1606   (void) new_connection (d, &sock);
   1607 
   1608   pos = CFG_BYTES;
   1609   while ( (pos + 2 <= size) &&
   1610           (nseg < MAX_SEGMENTS) )
   1611   {
   1612     unsigned int hdr = (unsigned int) data[pos]
   1613                        | ((unsigned int) data[pos + 1] << 8);
   1614     unsigned int op = hdr >> 14;
   1615     size_t slen = (size_t) (hdr & 0x3FFF);
   1616 
   1617     pos += 2;
   1618     nseg++;
   1619     if (slen > size - pos)
   1620       slen = size - pos;
   1621 
   1622     if ( (3 == op) &&
   1623          (nconn < cfg.nconn_max) )
   1624     {
   1625       close_connection (d, &sock);
   1626       (void) new_connection (d, &sock);
   1627       nconn++;
   1628     }
   1629     if (0 != slen)
   1630       send_all (d, sock, data + pos, slen);
   1631     pos += slen;
   1632     if (cfg.uses_threads)
   1633       continue;                 /* the threaded shape drains at close */
   1634     pump (d, sock, (0 == op) ? PUMP_ROUNDS : PUMP_ROUNDS_LONG);
   1635   }
   1636 
   1637   close_connection (d, &sock);
   1638   pump (d, sock, 4);
   1639   if (0 <= rsock)
   1640   {
   1641     (void) shutdown (rsock, SHUT_WR);
   1642     if (cfg.uses_threads)
   1643       wait_threaded (rsock);
   1644     else
   1645       pump (d, rsock, 4);
   1646     (void) close (rsock);
   1647     rsock = -1;
   1648   }
   1649 
   1650   /* A connection left suspended makes MHD_stop_daemon() MHD_PANIC(), and
   1651      MHD_resume_connection() alone is not enough: it only raises a flag,
   1652      and the connection is taken off the daemon's suspended list by
   1653      MHD_run().  So flush and run until nothing is parked any more.
   1654      tearing_down keeps the handler from parking anything new, which is
   1655      what bounds this loop; the cap is only a backstop. */
   1656   tearing_down = 1;
   1657   if (! cfg.uses_threads)
   1658   {
   1659     unsigned int i;
   1660 
   1661     for (i = 0; i < MAX_CONNECTIONS + 2u; i++)
   1662     {
   1663       if (! pending_resume_flush ())
   1664         break;
   1665       (void) MHD_run (d);
   1666     }
   1667   }
   1668 
   1669   if (cfg.quiesce)
   1670   {
   1671     /* The returned socket belongs to the caller from here on, and with
   1672        internal threads it must not be closed before MHD_stop_daemon()
   1673        has joined them. */
   1674     quiesced = MHD_quiesce_daemon (d);
   1675   }
   1676   MHD_stop_daemon (d);
   1677   if (MHD_INVALID_SOCKET != quiesced)
   1678     (void) close ((int) quiesced);
   1679   return 0;
   1680 }
   1681 
   1682 
   1683 /* ------------------------------------------------------------------ */
   1684 /* Structure-aware generator                                           */
   1685 /* ------------------------------------------------------------------ */
   1686 
   1687 /* Defined unconditionally, exactly like the rest of the harness API:
   1688    only main() may live behind #ifndef FUZZ_NO_MAIN, and fuzz_common.h
   1689    already declares these three with FUZZ_UNUSED so that the libFuzzer
   1690    and AFL++ builds, which never call them, compile without a warning. */
   1691 
   1692 struct sbuf
   1693 {
   1694   uint8_t *p;
   1695   size_t len;
   1696   size_t cap;
   1697 };
   1698 
   1699 
   1700 static void
   1701 sb_raw (struct sbuf *b,
   1702         const void *s,
   1703         size_t n)
   1704 {
   1705   if (b->len + n > b->cap)
   1706     n = b->cap - b->len;
   1707   memcpy (b->p + b->len, s, n);
   1708   b->len += n;
   1709 }
   1710 
   1711 
   1712 static void
   1713 sb_str (struct sbuf *b,
   1714         const char *s)
   1715 {
   1716   sb_raw (b, s, strlen (s));
   1717 }
   1718 
   1719 
   1720 static void
   1721 sb_u64 (struct sbuf *b,
   1722         uint64_t v,
   1723         int hex)
   1724 {
   1725   char tmp[32];
   1726 
   1727   (void) snprintf (tmp, sizeof (tmp),
   1728                    hex ? "%llx" : "%llu",
   1729                    (unsigned long long) v);
   1730   sb_str (b, tmp);
   1731 }
   1732 
   1733 
   1734 static const char *const gen_methods[] = {
   1735   "GET", "POST", "HEAD", "PUT", "OPTIONS", "DELETE", "TRACE", "CONNECT",
   1736   "PATCH", "get", "BREW", ""
   1737 };
   1738 
   1739 static const char *const gen_targets[] = {
   1740   "/", "/a", "/a/b/c", "*", "http://x/a", "/%41%42", "/a?b=c&d",
   1741   "/very/long/path/that/does/not/fit/into/a/small/connection/memory/pool",
   1742   "/a?novalue", "//", "/.%2e/", "/\x01"
   1743 };
   1744 
   1745 static const char *const gen_versions[] = {
   1746   "HTTP/1.1", "HTTP/1.0", "HTTP/1.2", "HTTP/0.9", "HTTP/1", ""
   1747 };
   1748 
   1749 static const char *const gen_hdr_names[] = {
   1750   "Host", "Connection", "Accept", "User-Agent", "Cookie", "Expect",
   1751   "Content-Type", "X-Fuzz", "Upgrade", "Accept-Encoding", "Range",
   1752   "If-Modified-Since"
   1753 };
   1754 
   1755 static const char *const gen_hdr_values[] = {
   1756   "x", "keep-alive", "close", "*/*", "a=b; c=d", "100-continue",
   1757   "text/plain", "1", "fuzz-protocol", "gzip", "bytes=0-1", "chunked"
   1758 };
   1759 
   1760 
   1761 /**
   1762  * Emit one HTTP request into @a b.
   1763  *
   1764  * The shapes are deliberately unambitious -- the request parser is
   1765  * fuzz_request's subject, not this harness's.  What matters here is that
   1766  * the bytes form something MHD will actually take through its state
   1767  * machine under whatever daemon configuration the configuration bytes
   1768  * describe, so that the option handling is exercised against a live
   1769  * connection rather than against a connection MHD drops on the first
   1770  * byte.
   1771  */
   1772 static void
   1773 gen_request (struct fuzz_rng *rng,
   1774              struct sbuf *b,
   1775              unsigned int shape)
   1776 {
   1777   unsigned int nhdr;
   1778   unsigned int i;
   1779 
   1780   switch (shape % 10)
   1781   {
   1782   case 9:
   1783     /* Not HTTP at all: MHD has to reject it, which is its own path. */
   1784     for (i = 0; i < 24; i++)
   1785     {
   1786       uint8_t c = fuzz_byte (rng);
   1787 
   1788       sb_raw (b, &c, 1);
   1789     }
   1790     return;
   1791   case 6:
   1792     /* Two pipelined requests on one connection. */
   1793     sb_str (b, "GET /a HTTP/1.1\r\nHost: x\r\n\r\n");
   1794     sb_str (b, "GET /b HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n");
   1795     return;
   1796   default:
   1797     break;
   1798   }
   1799 
   1800   sb_str (b, gen_methods[fuzz_below (rng, (uint32_t) (sizeof (gen_methods)
   1801                                                       / sizeof (gen_methods[0]
   1802                                                                 )))]);
   1803   sb_str (b, " ");
   1804   sb_str (b, gen_targets[fuzz_below (rng, (uint32_t) (sizeof (gen_targets)
   1805                                                       / sizeof (gen_targets[0]
   1806                                                                 )))]);
   1807   sb_str (b, " ");
   1808   sb_str (b, gen_versions[fuzz_below (rng,
   1809                                       (uint32_t) (sizeof (gen_versions)
   1810                                                   / sizeof (gen_versions[0])))
   1811           ]);
   1812   sb_str (b, "\r\n");
   1813 
   1814   nhdr = (5 == (shape % 10)) ? (8 + fuzz_below (rng, 24)) : fuzz_below (rng, 5);
   1815   for (i = 0; i < nhdr; i++)
   1816   {
   1817     sb_str (b, gen_hdr_names[fuzz_below (rng,
   1818                                          (uint32_t) (sizeof (gen_hdr_names)
   1819                                                      / sizeof (gen_hdr_names[0]
   1820                                                                )))]);
   1821     sb_str (b, ": ");
   1822     sb_str (b, gen_hdr_values[fuzz_below (rng,
   1823                                           (uint32_t) (sizeof (gen_hdr_values)
   1824                                                       / sizeof (gen_hdr_values[
   1825                                                                   0])))]);
   1826     sb_str (b, "\r\n");
   1827   }
   1828 
   1829   switch (shape % 10)
   1830   {
   1831   case 2:                      /* Content-Length body */
   1832     {
   1833       uint32_t n = fuzz_below (rng, 64);
   1834 
   1835       sb_str (b, "Content-Length: ");
   1836       sb_u64 (b, n, 0);
   1837       sb_str (b, "\r\n\r\n");
   1838       for (i = 0; i < n; i++)
   1839         sb_str (b, "A");
   1840       break;
   1841     }
   1842   case 3:                      /* chunked body */
   1843     {
   1844       unsigned int nch = 1 + fuzz_below (rng, 3);
   1845 
   1846       sb_str (b, "Transfer-Encoding: chunked\r\n\r\n");
   1847       for (i = 0; i < nch; i++)
   1848       {
   1849         uint32_t n = 1 + fuzz_below (rng, 16);
   1850         uint32_t k;
   1851 
   1852         sb_u64 (b, n, 1);
   1853         sb_str (b, "\r\n");
   1854         for (k = 0; k < n; k++)
   1855           sb_str (b, "B");
   1856         sb_str (b, "\r\n");
   1857       }
   1858       sb_str (b, "0\r\n\r\n");
   1859       break;
   1860     }
   1861   case 4:                      /* expect 100-continue */
   1862     sb_str (b, "Expect: 100-continue\r\nContent-Length: 4\r\n\r\nabcd");
   1863     break;
   1864   case 7:                      /* upgrade request */
   1865     sb_str (b, "Connection: Upgrade\r\nUpgrade: fuzz-protocol\r\n\r\n");
   1866     break;
   1867   case 8:                      /* truncated: MHD keeps waiting for more */
   1868     sb_str (b, "X-Trunc: ");
   1869     break;
   1870   default:
   1871     sb_str (b, "\r\n");
   1872     break;
   1873   }
   1874 }
   1875 
   1876 
   1877 /**
   1878  * Serialise @a body into the segment stream understood by
   1879  * LLVMFuzzerTestOneInput().
   1880  */
   1881 static void
   1882 emit_segments (struct fuzz_rng *rng,
   1883                struct sbuf *out,
   1884                const uint8_t *body,
   1885                size_t body_len,
   1886                int new_conn_first)
   1887 {
   1888   size_t off = 0;
   1889   int first = 1;
   1890 
   1891   while (off < body_len)
   1892   {
   1893     size_t chunk;
   1894     unsigned int op;
   1895     uint8_t hdr[2];
   1896     unsigned int hv;
   1897 
   1898     switch (fuzz_below (rng, 5))
   1899     {
   1900     case 0:
   1901       chunk = 1;
   1902       break;
   1903     case 1:
   1904       chunk = 2 + fuzz_below (rng, 8);
   1905       break;
   1906     default:
   1907       chunk = body_len - off;
   1908       break;
   1909     }
   1910     if (chunk > body_len - off)
   1911       chunk = body_len - off;
   1912     if (chunk > 0x3FFF)
   1913       chunk = 0x3FFF;
   1914     op = (first && new_conn_first) ? 3u : (fuzz_chance (rng, 5) ? 2u : 0u);
   1915     hv = (op << 14) | (unsigned int) chunk;
   1916     hdr[0] = (uint8_t) (hv & 0xFF);
   1917     hdr[1] = (uint8_t) (hv >> 8);
   1918     if (out->len + 2 + chunk > out->cap)
   1919       return;
   1920     sb_raw (out, hdr, 2);
   1921     sb_raw (out, body + off, chunk);
   1922     off += chunk;
   1923     first = 0;
   1924   }
   1925 }
   1926 
   1927 
   1928 /**
   1929  * The generator.
   1930  *
   1931  * Purely random configuration bytes are already useful for this harness
   1932  * -- unlike an HTTP request, an option array has no grammar to get wrong
   1933  * -- but two things still need help.  Byte 0 is biased into the range of
   1934  * mode_tbl[] so that most iterations get a daemon that actually starts,
   1935  * and the tail of the input has to look like HTTP, or MHD closes every
   1936  * connection before any of the configured behaviour has a chance to
   1937  * matter.
   1938  */
   1939 static size_t
   1940 fuzz_generate (struct fuzz_rng *rng,
   1941                uint8_t *buf,
   1942                size_t cap)
   1943 {
   1944   struct sbuf out;
   1945   uint8_t cfg_bytes[CFG_BYTES];
   1946   uint8_t req[GEN_BUF_SIZE];
   1947   struct sbuf rb;
   1948   unsigned int nreq;
   1949   unsigned int i;
   1950 
   1951   out.p = buf;
   1952   out.len = 0;
   1953   out.cap = cap;
   1954 
   1955   for (i = 0; i < CFG_BYTES; i++)
   1956     cfg_bytes[i] = fuzz_byte (rng);
   1957 
   1958   /* Byte 0 selects the daemon shape; keep it inside the table so that
   1959      the value is not folded by the modulo in an uneven way. */
   1960   cfg_bytes[0] = (uint8_t) fuzz_below (rng, (uint32_t) MODE_COUNT);
   1961   /* The raw flag escape is 1 in 4 of the byte-2 values, which is far too
   1962      often: those daemons mostly fail to start and never reach the option
   1963      handling.  Clear the escape unless it is explicitly rolled. */
   1964   if (! fuzz_chance (rng, 10))
   1965     cfg_bytes[2] &= (uint8_t) ~0xC0u;
   1966   else
   1967     cfg_bytes[2] |= (uint8_t) 0xC0u;
   1968   /* Likewise the deliberately invalid option number: useful, but every
   1969      input carrying it ends in MHD_start_daemon() == NULL. */
   1970   if (! fuzz_chance (rng, 20))
   1971     cfg_bytes[14] &= (uint8_t) ~0x40u;
   1972 
   1973   sb_raw (&out, cfg_bytes, CFG_BYTES);
   1974 
   1975   nreq = 1u + (fuzz_chance (rng, 4) ? 1u : 0u);
   1976   for (i = 0; i < nreq; i++)
   1977   {
   1978     rb.p = req;
   1979     rb.len = 0;
   1980     rb.cap = sizeof (req);
   1981     gen_request (rng, &rb, fuzz_below (rng, 10));
   1982     emit_segments (rng, &out, req, rb.len,
   1983                    (0 != i) || fuzz_chance (rng, 6));
   1984   }
   1985   return out.len;
   1986 }
   1987 
   1988 
   1989 /* ------------------------------------------------------------------ */
   1990 /* Built-in seed corpus                                                */
   1991 /* ------------------------------------------------------------------ */
   1992 
   1993 /**
   1994  * A seed is sixteen configuration bytes plus one request, rendered into
   1995  * the wire format at run time so that segment lengths never have to be
   1996  * spelled out by hand.
   1997  *
   1998  * Every seed turns on exactly one area, so that a corpus minimiser keeps
   1999  * them distinguishable, and the configuration bytes of a seed that does
   2000  * not care about an area are zero -- which is the plainest setting:
   2001  * external polling with select(), no listen socket, no options at all,
   2002  * one connection, MHD_run() as the event loop.
   2003  */
   2004 struct seed_def
   2005 {
   2006   const char *name;
   2007   unsigned char cfg[CFG_BYTES];
   2008   const char *req;
   2009 };
   2010 
   2011 /* Byte positions inside seed_def::cfg, for readability. */
   2012 #define C_MODE 0
   2013 #define C_FLAGA 1
   2014 #define C_FLAGB 2
   2015 #define C_OPTA 3
   2016 #define C_OPTB 4
   2017 #define C_OPTC 5
   2018 #define C_VAL_MEM 6
   2019 #define C_VAL_CONN 7
   2020 #define C_VAL_THR 8
   2021 #define C_VAL_DAUTH 9
   2022 #define C_VAL_DISC 10
   2023 #define C_VAL_SOCK 11
   2024 #define C_DRIVE 12
   2025 #define C_HANDLER 13
   2026 #define C_OPTD 14
   2027 #define C_SPARE 15
   2028 
   2029 #define REQ_PLAIN "GET /a HTTP/1.1\r\nHost: x\r\n\r\n"
   2030 #define REQ_CLOSE "GET /a HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n"
   2031 #define REQ_POST \
   2032         "POST /a HTTP/1.1\r\nHost: x\r\nContent-Length: 4\r\n\r\nabcd"
   2033 #define REQ_CHUNKED \
   2034         "POST /a HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n" \
   2035         "\r\n3\r\nabc\r\n0\r\n\r\n"
   2036 
   2037 static const struct seed_def seeds[] = {
   2038   /* ---- the event loops, all external ---- */
   2039   { "plain-external-run",
   2040     { 0 }, REQ_PLAIN },
   2041   { "external-fdset2",
   2042     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 | 0x08, 0, 0, 0 },
   2043     REQ_PLAIN },
   2044   { "external-run-wait",
   2045     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02, 0, 0, 0 },
   2046     REQ_PLAIN },
   2047   { "external-fdset-v1",
   2048     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0, 0, 0 },
   2049     REQ_PLAIN },
   2050   { "external-epoll",
   2051     { 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2052     REQ_PLAIN },
   2053   { "external-auto",
   2054     { 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2055     REQ_PLAIN },
   2056 
   2057   /* ---- the daemon shapes that run their own threads ---- */
   2058   { "internal-thread-select",
   2059     { 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2060     REQ_CLOSE },
   2061   { "internal-thread-poll",
   2062     { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2063     REQ_CLOSE },
   2064   { "internal-thread-epoll",
   2065     { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2066     REQ_CLOSE },
   2067   { "thread-per-connection",
   2068     { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2069     REQ_CLOSE },
   2070   { "thread-per-connection-poll",
   2071     { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2072     REQ_CLOSE },
   2073   /* A thread pool needs MHD_OPTION_THREAD_POOL_SIZE (option mask A bit
   2074      5) on top of an internal polling thread, and is rejected outright
   2075      with thread-per-connection. */
   2076   { "thread-pool",
   2077     { 18, 0, 0, 0x20, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0, 0, 0 },
   2078     REQ_CLOSE },
   2079   { "thread-pool-epoll-stack",
   2080     { 20, 0, 0, 0x20 | 0x40, 0, 0, 0, 0, 0x10 | 0x20, 0, 0, 0, 0, 0, 0, 0 },
   2081     REQ_CLOSE },
   2082 
   2083   /* ---- a real listening socket ---- */
   2084   { "listen-socket",
   2085     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2086     REQ_PLAIN },
   2087   { "listen-socket-reuse-backlog",
   2088     { 0, 0, 0x01, 0x80, 0x01, 0, 0, 0, 0, 0, 0, 0x01 | 0x06, 0, 0, 0, 0 },
   2089     REQ_PLAIN },
   2090   { "listen-socket-sockaddr",
   2091     { 0, 0, 0x01, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2092     REQ_PLAIN },
   2093   { "listen-socket-ipv6-dual",
   2094     { 0, 0, 0x01 | 0x02 | 0x04, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2095     REQ_PLAIN },
   2096   { "listen-socket-quiesce",
   2097     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04 | 0x08, 0, 0, 0 },
   2098     REQ_PLAIN },
   2099   { "listen-socket-internal-thread",
   2100     { 18, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0, 0, 0 },
   2101     REQ_CLOSE },
   2102 
   2103   /* ---- the accept() path: a real client on the listening socket ----
   2104      Byte 13 bit 0x40|0x80 asks for the connect(), bit 0x10 installs the
   2105      accept policy callback and bit 0x20 makes it say no.  Without these
   2106      MHD_accept_connection() and the listen-socket branches of the three
   2107      event loops are never entered at all: MHD_add_connection() bypasses
   2108      accept() completely. */
   2109   { "real-connect",
   2110     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2111     REQ_PLAIN },
   2112   { "real-connect-accept-policy",
   2113     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0 | 0x10, 0, 0 },
   2114     REQ_PLAIN },
   2115   { "real-connect-accept-denied",
   2116     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0 | 0x10 | 0x20, 0, 0 },
   2117     REQ_PLAIN },
   2118   { "real-connect-internal-thread",
   2119     { 18, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2120     REQ_CLOSE },
   2121   { "real-connect-external-epoll",
   2122     { 12, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xC0, 0, 0 },
   2123     REQ_PLAIN },
   2124 
   2125   /* ---- the memory options ---- */
   2126   { "tiny-pool",
   2127     { 0, 0, 0, 0x01 | 0x02, 0, 0, 0x01 | 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2128     REQ_PLAIN },
   2129   { "big-pool-big-increment",
   2130     { 0, 0, 0, 0x01 | 0x02, 0, 0, 0x0C | 0x60, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2131     REQ_POST },
   2132 
   2133   /* ---- the connection limits ---- */
   2134   { "connection-limit-one",
   2135     { 0, 0, 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0xC0, 0, 0, 0 },
   2136     REQ_PLAIN },
   2137   { "per-ip-limit-one",
   2138     { 0, 0, 0, 0x08, 0, 0, 0, 0x10, 0, 0, 0, 0, 0xC0, 0, 0, 0 },
   2139     REQ_PLAIN },
   2140   { "connection-limit-zero",
   2141     { 0, 0, 0, 0x04, 0, 0, 0, 0x00, 0, 0, 0, 0, 0, 0, 0, 0 },
   2142     REQ_PLAIN },
   2143   { "connection-timeout",
   2144     { 0, 0, 0, 0x10, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0 },
   2145     REQ_PLAIN },
   2146 
   2147   /* ---- parsing discipline and insanity ---- */
   2148   { "discipline-lowest",
   2149     { 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0 },
   2150     "GET /a HTTP/1.1\r\n Host: x\r\n\r\n" },
   2151   { "discipline-highest-pedantic",
   2152     { 0, 0x01, 0, 0, 0x10, 0, 0, 0, 0, 0, 0x05, 0, 0, 0, 0, 0 },
   2153     REQ_PLAIN },
   2154   { "strict-for-client",
   2155     { 0, 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0x00, 0, 0, 0, 0, 0 },
   2156     REQ_PLAIN },
   2157   { "server-insanity",
   2158     { 0, 0, 0, 0, 0x04, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0 },
   2159     REQ_PLAIN },
   2160   { "bin-zero-in-uri-path",
   2161     { 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0 },
   2162     "GET /a%00b HTTP/1.1\r\nHost: x\r\n\r\n" },
   2163   { "app-fd-setsize",
   2164     { 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0x00, 0x01, 0, 0, 0 },
   2165     REQ_PLAIN },
   2166 
   2167   /* ---- the callbacks ---- */
   2168   { "notify-completed",
   2169     { 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2170     REQ_PLAIN },
   2171   { "notify-connection",
   2172     { 0, 0, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2173     REQ_PLAIN },
   2174   { "uri-log-callback",
   2175     { 0, 0, 0, 0, 0, 0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2176     "GET /a?q=%41 HTTP/1.1\r\nHost: x\r\n\r\n" },
   2177   { "external-logger",
   2178     { 0, 0x40, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2179     REQ_PLAIN },
   2180   { "unescape-callback",
   2181     { 0, 0, 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2182     "GET /%41%42?a=%43 HTTP/1.1\r\nHost: x\r\n\r\n" },
   2183   { "all-callbacks-error-log",
   2184     { 0, 0x40, 0, 0, 0, 0x01 | 0x02 | 0x04 | 0x08 | 0x10,
   2185       0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2186     REQ_PLAIN },
   2187 
   2188   /* ---- digest-auth related options ---- */
   2189   { "digest-random",
   2190     { 0, 0, 0, 0, 0x02, 0x20, 0, 0, 0, 0x02, 0, 0, 0, 0, 0, 0 },
   2191     REQ_PLAIN },
   2192   { "digest-random-copy",
   2193     { 0, 0, 0, 0, 0x02, 0x20 | 0x40, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0 },
   2194     REQ_PLAIN },
   2195   { "digest-nonce-bind-and-defaults",
   2196     { 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0x3C, 0, 0, 0, 0,
   2197       0x01 | 0x02 | 0x04, 0x11 },
   2198     REQ_PLAIN },
   2199 
   2200   /* ---- suspend / resume ---- */
   2201   { "suspend-immediate",
   2202     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 },
   2203     REQ_PLAIN },
   2204   { "suspend-deferred",
   2205     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0 },
   2206     REQ_PLAIN },
   2207   { "suspend-deferred-two-connections",
   2208     { 0, 0x04, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0x20 | 0x40, 0, 0, 0 },
   2209     REQ_PLAIN },
   2210 
   2211   /* ---- the remaining flag bits ---- */
   2212   { "turbo-itc-suppress-date",
   2213     { 0, 0x02 | 0x10 | 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2214     REQ_PLAIN },
   2215   { "allow-upgrade",
   2216     { 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2217     "GET / HTTP/1.1\r\nHost: x\r\nConnection: Upgrade\r\n"
   2218     "Upgrade: fuzz-protocol\r\n\r\n" },
   2219   { "no-thread-safety",
   2220     { 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2221     REQ_PLAIN },
   2222   { "tcp-fastopen-listen",
   2223     { 0, 0, 0x01 | 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0x08, 0 },
   2224     REQ_PLAIN },
   2225   { "sigpipe-handled-by-app",
   2226     { 0, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2227     REQ_PLAIN },
   2228   { "listen-socket-option-invalid-fd",
   2229     { 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0 },
   2230     REQ_PLAIN },
   2231 
   2232   /* ---- inputs whose daemon must not start ---- */
   2233   /* Raw flag escape: MHD_USE_POLL together with MHD_USE_EPOLL. */
   2234   { "raw-flags-poll-and-epoll",
   2235     { 0, 0x40, 0xC0 | 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2236     REQ_PLAIN },
   2237   /* Raw flag escape: MHD_USE_EPOLL with MHD_USE_THREAD_PER_CONNECTION. */
   2238   { "raw-flags-epoll-thread-per-conn",
   2239     { 0, 0x04 | 0x08, 0xC0 | 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2240     REQ_PLAIN },
   2241   /* An option number MHD does not know. */
   2242   { "invalid-option-number",
   2243     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0 },
   2244     REQ_PLAIN },
   2245   /* MHD_OPTION_THREAD_POOL_SIZE without an internal polling thread. */
   2246   { "thread-pool-without-threads",
   2247     { 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
   2248     REQ_PLAIN },
   2249 
   2250   /* ---- the handler behaviours ---- */
   2251   { "handler-returns-no",
   2252     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0, 0 },
   2253     REQ_PLAIN },
   2254   { "empty-and-copied-responses",
   2255     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 | 0x08, 0, 0 },
   2256     REQ_CHUNKED },
   2257   { "error-response",
   2258     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0, 0 },
   2259     REQ_POST },
   2260 
   2261   /* ---- everything at once ---- */
   2262   { "kitchen-sink-external",
   2263     { 0, 0x02 | 0x04 | 0x10 | 0x20 | 0x40, 0x01,
   2264       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x80,
   2265       0x02 | 0x10 | 0x20 | 0x40 | 0x80,
   2266       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20,
   2267       0x63, 0x45, 0x21, 0x13, 0x02, 0x0A,
   2268       0x01 | 0x04 | 0x08 | 0x20, 0x08, 0x01 | 0x02 | 0x04 | 0x10, 0x33 },
   2269     REQ_POST },
   2270   { "kitchen-sink-thread-pool",
   2271     { 18, 0x02 | 0x10 | 0x20 | 0x40, 0x01,
   2272       0x01 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
   2273       0x01 | 0x02 | 0x80,
   2274       0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20,
   2275       0x03, 0x46, 0x39, 0x02, 0x00, 0x0A,
   2276       0x04 | 0x08, 0x00, 0x01 | 0x08, 0x22 },
   2277     REQ_CLOSE }
   2278 };
   2279 
   2280 static uint8_t seed_render_buf[1024];
   2281 
   2282 
   2283 static size_t
   2284 fuzz_seed_count (void)
   2285 {
   2286   return sizeof (seeds) / sizeof (seeds[0]);
   2287 }
   2288 
   2289 
   2290 static const uint8_t *
   2291 fuzz_seed_get (size_t idx,
   2292                size_t *len)
   2293 {
   2294   const struct seed_def *sd = &seeds[idx];
   2295   struct sbuf b;
   2296 
   2297   b.p = seed_render_buf;
   2298   b.len = 0;
   2299   b.cap = sizeof (seed_render_buf);
   2300   sb_raw (&b, sd->cfg, CFG_BYTES);
   2301   if (NULL != sd->req)
   2302   {
   2303     size_t n = strlen (sd->req);
   2304     unsigned int hv;
   2305     uint8_t hdr[2];
   2306 
   2307     if (n > 0x3FFF)
   2308       n = 0x3FFF;
   2309     hv = (0u << 14) | (unsigned int) n;
   2310     hdr[0] = (uint8_t) (hv & 0xFF);
   2311     hdr[1] = (uint8_t) (hv >> 8);
   2312     sb_raw (&b, hdr, 2);
   2313     sb_raw (&b, sd->req, n);
   2314   }
   2315   *len = b.len;
   2316   return seed_render_buf;
   2317 }