GNU libmicrohttpd 1.0.9
Loading...
Searching...
No Matches
fuzz_common.h
Go to the documentation of this file.
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
44#ifndef MHD_FUZZ_COMMON_H
45#define MHD_FUZZ_COMMON_H 1
46
47#include <stdint.h>
48#include <stddef.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53#include <fcntl.h>
54#include <signal.h>
55#include <errno.h>
56#include <sys/stat.h>
57#include <sys/types.h>
58#include <dirent.h>
59
60#ifndef FUZZ_HARNESS_NAME
61#define FUZZ_HARNESS_NAME "fuzz"
62#endif
63
67#define FUZZ_UNUSED __attribute__ ((unused))
68
72#ifndef FUZZ_MAX_INPUT
73#define FUZZ_MAX_INPUT 32768
74#endif
75
81#ifndef FUZZ_DEFAULT_ITERATIONS
82#define FUZZ_DEFAULT_ITERATIONS 3000
83#endif
84
88#ifndef FUZZ_DEFAULT_TIMEOUT
89#define FUZZ_DEFAULT_TIMEOUT 20
90#endif
91
92
93/* ------------------------------------------------------------------ */
94/* Interface to be implemented by each harness */
95/* ------------------------------------------------------------------ */
96
101int
102LLVMFuzzerTestOneInput (const uint8_t *data,
103 size_t size);
104
105struct fuzz_rng;
106
113FUZZ_UNUSED static size_t
115 uint8_t *buf,
116 size_t cap);
117
121FUZZ_UNUSED static size_t
123
129FUZZ_UNUSED static const uint8_t *
130fuzz_seed_get (size_t idx,
131 size_t *len);
132
133
134/* ------------------------------------------------------------------ */
135/* Deterministic PRNG */
136/* ------------------------------------------------------------------ */
137
139{
140 uint64_t s[4];
141};
142
143FUZZ_UNUSED static uint64_t
144fuzz_splitmix64 (uint64_t *x)
145{
146 uint64_t z;
147
148 *x += UINT64_C (0x9E3779B97F4A7C15);
149 z = *x;
150 z = (z ^ (z >> 30)) * UINT64_C (0xBF58476D1CE4E5B9);
151 z = (z ^ (z >> 27)) * UINT64_C (0x94D049BB133111EB);
152 return z ^ (z >> 31);
153}
154
155
156FUZZ_UNUSED static void
158 uint64_t seed)
159{
160 uint64_t x = seed;
161 unsigned int i;
162
163 for (i = 0; i < 4; i++)
164 r->s[i] = fuzz_splitmix64 (&x);
165}
166
167
168FUZZ_UNUSED static uint64_t
169fuzz_rot64 (uint64_t x,
170 unsigned int k)
171{
172 return (x << k) | (x >> (64 - k));
173}
174
175
180FUZZ_UNUSED static uint64_t
182{
183 const uint64_t res = fuzz_rot64 (r->s[1] * 5, 7) * 9;
184 const uint64_t t = r->s[1] << 17;
185
186 r->s[2] ^= r->s[0];
187 r->s[3] ^= r->s[1];
188 r->s[1] ^= r->s[2];
189 r->s[0] ^= r->s[3];
190 r->s[2] ^= t;
191 r->s[3] = fuzz_rot64 (r->s[3], 45);
192 return res;
193}
194
195
199FUZZ_UNUSED static uint32_t
201 uint32_t n)
202{
203 if (0 == n)
204 return 0;
205 return (uint32_t) (fuzz_next (r) % n);
206}
207
208
209FUZZ_UNUSED static uint8_t
211{
212 return (uint8_t) (fuzz_next (r) & 0xFF);
213}
214
215
219FUZZ_UNUSED static int
221 uint32_t n)
222{
223 return 0 == fuzz_below (r, n);
224}
225
226
227/* ------------------------------------------------------------------ */
228/* Global driver state */
229/* ------------------------------------------------------------------ */
230
240
245
252
253/* Only read by the built-in driver; under -DFUZZ_NO_MAIN (the libFuzzer
254 and AFL++ builds, see contrib/oss-fuzz/build.sh) they are written but
255 never read, which is not a defect. */
258static const uint8_t *fuzz_cur_input;
259static size_t fuzz_cur_input_len;
260static const char *fuzz_crash_dir = "crashes";
261
262/* Pre-rendered, so that the death/signal handlers stay
263 async-signal-safe (no snprintf, no malloc). */
264static char fuzz_crash_path[512];
265static char fuzz_crash_msg[512];
266static volatile sig_atomic_t fuzz_dumped;
267
268
269FUZZ_UNUSED static void
271 const void *buf,
272 size_t len)
273{
274 const char *p = (const char *) buf;
275
276 while (0 != len)
277 {
278 ssize_t w = write (fd, p, len);
279 if (0 >= w)
280 break;
281 p += w;
282 len -= (size_t) w;
283 }
284}
285
286
287FUZZ_UNUSED static void
288fuzz_msg (const char *s)
289{
290 fuzz_write_all (STDERR_FILENO, s, strlen (s));
291}
292
293
298FUZZ_UNUSED static void
300{
301 int fd;
302
303 if (fuzz_dumped)
304 return;
305 fuzz_dumped = 1;
306 if ( (NULL == fuzz_cur_input) ||
307 ('\0' == fuzz_crash_path[0]) )
308 return;
309 (void) mkdir (fuzz_crash_dir, 0755);
310 fd = open (fuzz_crash_path,
311 O_WRONLY | O_CREAT | O_TRUNC,
312 0644);
313 if (0 > fd)
314 {
315 fuzz_msg ("\n*** FUZZ: failed to write crash file ***\n");
316 return;
317 }
319 (void) close (fd);
320 fuzz_msg ("\n*** FUZZ: reproducer written to ");
322 fuzz_msg (" ***\n*** FUZZ: ");
324 fuzz_msg (" ***\n");
325}
326
327
328FUZZ_UNUSED static void
330{
332}
333
334
335FUZZ_UNUSED static void
337{
339 if (SIGALRM == sig)
340 {
341 fuzz_msg ("*** FUZZ: HANG detected (watchdog fired) ***\n");
342 _exit (99);
343 }
344 /* restore default handler and re-raise so that the usual
345 ASAN/abort diagnostics are produced */
346 signal (sig, SIG_DFL);
347 raise (sig);
348}
349
350
355FUZZ_UNUSED static void
356fuzz_report_finding (const char *what)
357{
358 size_t l = strlen (what);
359
360 if (l >= sizeof (fuzz_crash_msg))
361 l = sizeof (fuzz_crash_msg) - 1;
362 memcpy (fuzz_crash_msg, what, l);
363 fuzz_crash_msg[l] = '\0';
364 fuzz_msg ("\n*** FUZZ FINDING: ");
366 fuzz_msg (" ***\n");
368 abort ();
369}
370
371
372/* Weak declaration: resolved when built with ASAN (gcc or clang),
373 NULL otherwise. ASAN calls this right before it terminates the
374 process, which is the only reliable hook when abort_on_error=0. */
375extern void
376__sanitizer_set_death_callback (void (*cb)(void)) __attribute__ ((weak));
377
378
398FUZZ_UNUSED static void
400{
401 static int sigpipe_ignored;
402
403 if (sigpipe_ignored)
404 return;
405 sigpipe_ignored = 1;
406 (void) signal (SIGPIPE, SIG_IGN);
407}
408
409
410#ifndef FUZZ_NO_MAIN
411
412static void
414{
415 struct sigaction sa;
416
419 memset (&sa, 0, sizeof (sa));
420 sa.sa_handler = &fuzz_sig_handler;
421 sigemptyset (&sa.sa_mask);
422 sa.sa_flags = 0;
423 (void) sigaction (SIGABRT, &sa, NULL);
424 (void) sigaction (SIGSEGV, &sa, NULL);
425 (void) sigaction (SIGBUS, &sa, NULL);
426 (void) sigaction (SIGILL, &sa, NULL);
427 (void) sigaction (SIGFPE, &sa, NULL);
428 (void) sigaction (SIGALRM, &sa, NULL);
430}
431
432
437static void
438fuzz_set_current (const uint8_t *data,
439 size_t size,
440 const char *tag)
441{
443 fuzz_cur_input_len = size;
444 fuzz_dumped = 0;
445 (void) snprintf (fuzz_crash_path,
446 sizeof (fuzz_crash_path),
447 "%s/crash-%s-seed%llu-iter%llu.bin",
450 (unsigned long long) fuzz_cur_seed,
451 (unsigned long long) fuzz_cur_iter);
452 (void) snprintf (fuzz_crash_msg,
453 sizeof (fuzz_crash_msg),
454 "harness=%s seed=%llu iteration=%llu source=%s",
456 (unsigned long long) fuzz_cur_seed,
457 (unsigned long long) fuzz_cur_iter,
458 tag);
459}
460
461
462/* ------------------------------------------------------------------ */
463/* Generic byte-level mutator */
464/* ------------------------------------------------------------------ */
465
466static const uint8_t fuzz_interesting[] = {
467 0x00, 0x01, 0x07, 0x09, 0x0A, 0x0D, 0x20, 0x22, 0x25, 0x26, 0x27,
468 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x3A, 0x3B, 0x3D, 0x3F, 0x40,
469 0x5C, 0x7B, 0x7D, 0x7F, 0x80, 0xC0, 0xFE, 0xFF
470};
471
472static const char *const fuzz_interesting_str[] = {
473 "\r\n", "\r\n\r\n", "\n", "%", "%%NONCE%%", ";", "=", "\"", "\\",
474 "chunked", "Transfer-Encoding: ", "Content-Length: ", "algorithm=",
475 "userhash=true", "Authorization: Digest ", "Authorization: Basic ",
476 "boundary=", "multipart/form-data", "0\r\n\r\n", "?", "&",
477 "aaaaaaaaaaaaaaaa"
478};
479
480
490static size_t
492 uint8_t *buf,
493 size_t len,
494 size_t cap)
495{
496 uint32_t op;
497
498 if (0 == len)
499 {
500 buf[0] = fuzz_byte (rng);
501 return 1;
502 }
503 op = fuzz_below (rng, 10);
504 switch (op)
505 {
506 case 0: /* bit flip */
507 {
508 size_t p = fuzz_below (rng, (uint32_t) len);
509 buf[p] = (uint8_t) (buf[p] ^ (1u << fuzz_below (rng, 8)));
510 break;
511 }
512 case 1: /* random byte */
513 buf[fuzz_below (rng, (uint32_t) len)] = fuzz_byte (rng);
514 break;
515 case 2: /* interesting byte */
516 buf[fuzz_below (rng, (uint32_t) len)] =
518 (uint32_t) (sizeof (fuzz_interesting)))];
519 break;
520 case 3: /* add/sub small value */
521 {
522 size_t p = fuzz_below (rng, (uint32_t) len);
523 buf[p] = (uint8_t) (buf[p] + (int) fuzz_below (rng, 17) - 8);
524 break;
525 }
526 case 4: /* erase a run */
527 {
528 size_t p = fuzz_below (rng, (uint32_t) len);
529 size_t n = 1 + fuzz_below (rng, (uint32_t) (len - p));
530 memmove (buf + p, buf + p + n, len - p - n);
531 len -= n;
532 break;
533 }
534 case 5: /* insert repeated byte */
535 {
536 size_t p = fuzz_below (rng, (uint32_t) len + 1);
537 size_t n = 1 + fuzz_below (rng, 32);
538 uint8_t v = fuzz_byte (rng);
539 if (len + n > cap)
540 n = cap - len;
541 if (0 == n)
542 break;
543 memmove (buf + p + n, buf + p, len - p);
544 memset (buf + p, v, n);
545 len += n;
546 break;
547 }
548 case 6: /* duplicate a chunk */
549 {
550 size_t p = fuzz_below (rng, (uint32_t) len);
551 size_t n = 1 + fuzz_below (rng, (uint32_t) (len - p));
552 size_t d = fuzz_below (rng, (uint32_t) len + 1);
553 if (len + n > cap)
554 n = cap - len;
555 if (0 == n)
556 break;
557 memmove (buf + d + n, buf + d, len - d);
558 memmove (buf + d, buf + ((p >= d) ? (p + n) : p), n);
559 len += n;
560 break;
561 }
562 case 7: /* insert an interesting token */
563 {
564 const char *s =
566 (uint32_t)
567 (sizeof (fuzz_interesting_str)
568 / sizeof (fuzz_interesting_str[0])))];
569 size_t n = strlen (s);
570 size_t p = fuzz_below (rng, (uint32_t) len + 1);
571 if (len + n > cap)
572 break;
573 memmove (buf + p + n, buf + p, len - p);
574 memcpy (buf + p, s, n);
575 len += n;
576 break;
577 }
578 case 8: /* swap two bytes */
579 {
580 size_t a = fuzz_below (rng, (uint32_t) len);
581 size_t b = fuzz_below (rng, (uint32_t) len);
582 uint8_t t = buf[a];
583 buf[a] = buf[b];
584 buf[b] = t;
585 break;
586 }
587 default: /* truncate */
588 len = 1 + fuzz_below (rng, (uint32_t) len);
589 break;
590 }
591 return len;
592}
593
594
595/* ------------------------------------------------------------------ */
596/* Standalone driver */
597/* ------------------------------------------------------------------ */
598
599static int
600fuzz_run_file (const char *path)
601{
602 FILE *f;
603 uint8_t *buf;
604 size_t n;
605
606 f = fopen (path, "rb");
607 if (NULL == f)
608 {
609 fprintf (stderr,
610 "%s: cannot open '%s': %s\n",
612 path,
613 strerror (errno));
614 return 1;
615 }
616 buf = (uint8_t *) malloc (FUZZ_MAX_INPUT);
617 if (NULL == buf)
618 {
619 (void) fclose (f);
620 return 1;
621 }
622 n = fread (buf, 1, FUZZ_MAX_INPUT, f);
623 (void) fclose (f);
624 fuzz_pristine = 1;
625 fuzz_set_current (buf, n, path);
626 alarm (FUZZ_DEFAULT_TIMEOUT);
627 (void) LLVMFuzzerTestOneInput (buf, n);
628 alarm (0);
629 free (buf);
630 return 0;
631}
632
633
634static int
635fuzz_run_corpus_dir (const char *dir)
636{
637 DIR *d;
638 struct dirent *de;
639 char path[1024];
640 int ret = 0;
641 unsigned int cnt = 0;
642
643 d = opendir (dir);
644 if (NULL == d)
645 {
646 fprintf (stderr,
647 "%s: cannot open corpus dir '%s': %s\n",
649 dir,
650 strerror (errno));
651 return 1;
652 }
653 while (NULL != (de = readdir (d)))
654 {
655 struct stat sb;
656
657 if ('.' == de->d_name[0])
658 continue;
659 (void) snprintf (path, sizeof (path), "%s/%s", dir, de->d_name);
660 if ( (0 != stat (path, &sb)) ||
661 (! S_ISREG (sb.st_mode)) )
662 continue;
663 fuzz_cur_iter = cnt++;
664 ret |= fuzz_run_file (path);
665 }
666 (void) closedir (d);
667 printf ("%s: replayed %u corpus file(s) from %s\n",
668 FUZZ_HARNESS_NAME, cnt, dir);
669 return ret;
670}
671
672
673static void
674fuzz_usage (const char *argv0)
675{
676 printf (
677 "Usage: %s [OPTIONS] [FILE...]\n"
678 "\n"
679 "In-process fuzzing harness '%s' for GNU libmicrohttpd.\n"
680 "\n"
681 " --iterations=N number of generate/mutate iterations (default %d)\n"
682 " --seed=N PRNG seed; runs are fully reproducible (default 1)\n"
683 " --corpus-dir=DIR replay every regular file in DIR and exit\n"
684 " --file=PATH replay a single input and exit (crash reproduction)\n"
685 " --crash-dir=DIR where to write reproducers (default 'crashes')\n"
686 " --timeout=SEC per-iteration watchdog (default %d, 0 disables)\n"
687 " --write-corpus=DIR write the built-in seed corpus to DIR and exit\n"
688 " --skip-seeds do not replay the built-in seed corpus first\n"
689 " --verbose enable MHD's error log inside the harness\n"
690 " --help this text\n"
691 "\n"
692 "Environment: MHD_FUZZ_ITERATIONS, MHD_FUZZ_SEED, MHD_FUZZ_TIMEOUT,\n"
693 " MHD_FUZZ_CRASH_DIR, MHD_FUZZ_VERBOSE\n"
694 "\n"
695 "Bare FILE arguments are equivalent to --file=FILE (libFuzzer-style).\n",
696 argv0, FUZZ_HARNESS_NAME,
698}
699
700
701static int
702fuzz_write_corpus (const char *dir)
703{
704 size_t i;
705 size_t n = fuzz_seed_count ();
706
707 if ( (0 != mkdir (dir, 0755)) &&
708 (EEXIST != errno) )
709 {
710 fprintf (stderr, "%s: mkdir '%s': %s\n",
711 FUZZ_HARNESS_NAME, dir, strerror (errno));
712 return 1;
713 }
714 for (i = 0; i < n; i++)
715 {
716 char path[1024];
717 size_t len;
718 const uint8_t *s = fuzz_seed_get (i, &len);
719 FILE *f;
720
721 (void) snprintf (path, sizeof (path), "%s/%s-%02u.bin",
722 dir, FUZZ_HARNESS_NAME, (unsigned int) i);
723 f = fopen (path, "wb");
724 if (NULL == f)
725 {
726 fprintf (stderr, "%s: fopen '%s': %s\n",
727 FUZZ_HARNESS_NAME, path, strerror (errno));
728 return 1;
729 }
730 if (len != fwrite (s, 1, len, f))
731 {
732 (void) fclose (f);
733 return 1;
734 }
735 (void) fclose (f);
736 }
737 printf ("%s: wrote %u seed(s) to %s\n",
738 FUZZ_HARNESS_NAME, (unsigned int) n, dir);
739 return 0;
740}
741
742
743int
744main (int argc, char *const *argv)
745{
746 uint64_t iterations = FUZZ_DEFAULT_ITERATIONS;
747 uint64_t seed = 1;
748 unsigned int timeout = FUZZ_DEFAULT_TIMEOUT;
749 const char *corpus_dir = NULL;
750 const char *single_file = NULL;
751 const char *write_corpus = NULL;
752 struct fuzz_rng rng;
753 uint8_t *buf;
754 uint64_t i;
755 int j;
756 const char *e;
757 int ret = 0;
758
759 e = getenv ("MHD_FUZZ_ITERATIONS");
760 if (NULL != e)
761 iterations = strtoull (e, NULL, 10);
762 e = getenv ("MHD_FUZZ_SEED");
763 if (NULL != e)
764 seed = strtoull (e, NULL, 10);
765 e = getenv ("MHD_FUZZ_TIMEOUT");
766 if (NULL != e)
767 timeout = (unsigned int) strtoul (e, NULL, 10);
768 e = getenv ("MHD_FUZZ_CRASH_DIR");
769 if (NULL != e)
770 fuzz_crash_dir = e;
771 e = getenv ("MHD_FUZZ_VERBOSE");
772 if (NULL != e)
773 fuzz_verbose = (0 != atoi (e));
774 e = getenv ("MHD_FUZZ_SKIP_SEEDS");
775 if (NULL != e)
776 fuzz_skip_seeds = (0 != atoi (e));
777
778 for (j = 1; j < argc; j++)
779 {
780 const char *a = argv[j];
781
782 if (0 == strncmp (a, "--iterations=", 13))
783 iterations = strtoull (a + 13, NULL, 10);
784 else if (0 == strncmp (a, "--seed=", 7))
785 seed = strtoull (a + 7, NULL, 10);
786 else if (0 == strncmp (a, "--corpus-dir=", 13))
787 corpus_dir = a + 13;
788 else if (0 == strncmp (a, "--file=", 7))
789 single_file = a + 7;
790 else if (0 == strncmp (a, "--crash-dir=", 12))
791 fuzz_crash_dir = a + 12;
792 else if (0 == strncmp (a, "--timeout=", 10))
793 timeout = (unsigned int) strtoul (a + 10, NULL, 10);
794 else if (0 == strncmp (a, "--write-corpus=", 15))
795 write_corpus = a + 15;
796 else if (0 == strcmp (a, "--skip-seeds"))
797 fuzz_skip_seeds = 1;
798 else if (0 == strcmp (a, "--verbose"))
799 fuzz_verbose = 1;
800 else if ( (0 == strcmp (a, "--help")) ||
801 (0 == strcmp (a, "-h")) )
802 {
803 fuzz_usage (argv[0]);
804 return 0;
805 }
806 else if ('-' == a[0])
807 {
808 fprintf (stderr, "%s: unknown option '%s'\n", FUZZ_HARNESS_NAME, a);
809 fuzz_usage (argv[0]);
810 return 2;
811 }
812 else
813 single_file = a;
814 }
815
816 fuzz_cur_seed = seed;
818
819 if (NULL != write_corpus)
820 return fuzz_write_corpus (write_corpus);
821
822 if (NULL != single_file)
823 {
824 printf ("%s: replaying %s\n", FUZZ_HARNESS_NAME, single_file);
825 ret = fuzz_run_file (single_file);
826 printf ("%s: replay finished without a finding\n", FUZZ_HARNESS_NAME);
827 return ret;
828 }
829 if (NULL != corpus_dir)
830 return fuzz_run_corpus_dir (corpus_dir);
831
832 buf = (uint8_t *) malloc (FUZZ_MAX_INPUT);
833 if (NULL == buf)
834 return 1;
835 fuzz_rng_seed (&rng, seed);
836 printf ("%s: seed=%llu iterations=%llu\n",
838 (unsigned long long) seed,
839 (unsigned long long) iterations);
840 fflush (stdout);
841
842 for (i = 0; i < iterations; i++)
843 {
844 size_t len;
845 const char *tag;
846 uint32_t mode;
847
848 fuzz_cur_iter = i;
849 if ( (! fuzz_skip_seeds) &&
850 (i < fuzz_seed_count ()) )
851 {
852 size_t sl;
853 const uint8_t *s = fuzz_seed_get ((size_t) i, &sl);
854
855 if (sl > FUZZ_MAX_INPUT)
856 sl = FUZZ_MAX_INPUT;
857 memcpy (buf, s, sl);
858 len = sl;
859 fuzz_pristine = 1;
860 tag = "builtin-seed";
861 }
862 else
863 {
864 mode = fuzz_below (&rng, 100);
865 if (mode < 55)
866 {
867 fuzz_pristine = 1;
868 len = fuzz_generate (&rng, buf, FUZZ_MAX_INPUT);
869 tag = "generated";
870 }
871 else
872 {
873 unsigned int k;
874 unsigned int nmut;
875
876 if (mode < 85)
877 {
878 len = fuzz_generate (&rng, buf, FUZZ_MAX_INPUT);
879 tag = "generated+mutated";
880 }
881 else
882 {
883 size_t sl;
884 const uint8_t *s;
885
886 if (0 == fuzz_seed_count ())
887 {
888 len = fuzz_generate (&rng, buf, FUZZ_MAX_INPUT);
889 }
890 else
891 {
892 s = fuzz_seed_get (fuzz_below (&rng,
893 (uint32_t) fuzz_seed_count ()),
894 &sl);
895 if (sl > FUZZ_MAX_INPUT)
896 sl = FUZZ_MAX_INPUT;
897 memcpy (buf, s, sl);
898 len = sl;
899 }
900 tag = "seed+mutated";
901 }
902 fuzz_pristine = 0;
903 nmut = 1 + fuzz_below (&rng, 8);
904 for (k = 0; k < nmut; k++)
905 len = fuzz_mutate_once (&rng, buf, len, FUZZ_MAX_INPUT);
906 }
907 }
908 fuzz_set_current (buf, len, tag);
909 if (0 != timeout)
910 alarm (timeout);
911 (void) LLVMFuzzerTestOneInput (buf, len);
912 if (0 != timeout)
913 alarm (0);
914 }
915 free (buf);
916 printf ("%s: %llu iterations completed, no findings\n",
918 (unsigned long long) iterations);
919 return ret;
920}
921
922
923#endif /* ! FUZZ_NO_MAIN */
924
925#endif /* MHD_FUZZ_COMMON_H */
static const char * fuzz_crash_dir
static FUZZ_UNUSED int fuzz_pristine
static FUZZ_UNUSED void fuzz_dump_current(void)
static FUZZ_UNUSED uint64_t fuzz_splitmix64(uint64_t *x)
static size_t fuzz_cur_input_len
void __sanitizer_set_death_callback(void(*cb)(void)) __attribute__((weak))
#define FUZZ_UNUSED
Definition fuzz_common.h:67
static FUZZ_UNUSED void fuzz_rng_seed(struct fuzz_rng *r, uint64_t seed)
static FUZZ_UNUSED void fuzz_death_callback(void)
static void fuzz_set_current(const uint8_t *data, size_t size, const char *tag)
static int fuzz_write_corpus(const char *dir)
static FUZZ_UNUSED const uint8_t * fuzz_seed_get(size_t idx, size_t *len)
#define FUZZ_DEFAULT_TIMEOUT
Definition fuzz_common.h:89
#define FUZZ_HARNESS_NAME
Definition fuzz_common.h:61
static FUZZ_UNUSED void fuzz_ignore_sigpipe(void)
static FUZZ_UNUSED int fuzz_verbose
static size_t fuzz_mutate_once(struct fuzz_rng *rng, uint8_t *buf, size_t len, size_t cap)
static FUZZ_UNUSED uint64_t fuzz_next(struct fuzz_rng *r)
static void fuzz_usage(const char *argv0)
static FUZZ_UNUSED uint64_t fuzz_cur_iter
static FUZZ_UNUSED void fuzz_sig_handler(int sig)
static FUZZ_UNUSED uint32_t fuzz_below(struct fuzz_rng *r, uint32_t n)
static FUZZ_UNUSED int fuzz_skip_seeds
static const uint8_t * fuzz_cur_input
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
static FUZZ_UNUSED void fuzz_msg(const char *s)
#define FUZZ_DEFAULT_ITERATIONS
Definition fuzz_common.h:82
static const char *const fuzz_interesting_str[]
#define FUZZ_MAX_INPUT
Definition fuzz_common.h:73
static FUZZ_UNUSED size_t fuzz_seed_count(void)
static volatile sig_atomic_t fuzz_dumped
static char fuzz_crash_path[512]
static int fuzz_run_file(const char *path)
static FUZZ_UNUSED uint64_t fuzz_rot64(uint64_t x, unsigned int k)
static const uint8_t fuzz_interesting[]
static FUZZ_UNUSED uint8_t fuzz_byte(struct fuzz_rng *r)
static FUZZ_UNUSED size_t fuzz_generate(struct fuzz_rng *rng, uint8_t *buf, size_t cap)
int main(int argc, char *const *argv)
static FUZZ_UNUSED void fuzz_write_all(int fd, const void *buf, size_t len)
static FUZZ_UNUSED void fuzz_report_finding(const char *what)
static FUZZ_UNUSED int fuzz_chance(struct fuzz_rng *r, uint32_t n)
static char fuzz_crash_msg[512]
static void fuzz_install_handlers(void)
static int fuzz_run_corpus_dir(const char *dir)
static FUZZ_UNUSED uint64_t fuzz_cur_seed
#define NULL
int fd
void * data
uint64_t s[4]