xref: /qemu/tests/qtest/fuzz/fuzz.h (revision 5f6fd09a9729d31225b6eaec5df05d19a5bdfda4)
1*5f6fd09aSAlexander Bulekov /*
2*5f6fd09aSAlexander Bulekov  * fuzzing driver
3*5f6fd09aSAlexander Bulekov  *
4*5f6fd09aSAlexander Bulekov  * Copyright Red Hat Inc., 2019
5*5f6fd09aSAlexander Bulekov  *
6*5f6fd09aSAlexander Bulekov  * Authors:
7*5f6fd09aSAlexander Bulekov  *  Alexander Bulekov   <alxndr@bu.edu>
8*5f6fd09aSAlexander Bulekov  *
9*5f6fd09aSAlexander Bulekov  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10*5f6fd09aSAlexander Bulekov  * See the COPYING file in the top-level directory.
11*5f6fd09aSAlexander Bulekov  *
12*5f6fd09aSAlexander Bulekov  */
13*5f6fd09aSAlexander Bulekov 
14*5f6fd09aSAlexander Bulekov #ifndef FUZZER_H_
15*5f6fd09aSAlexander Bulekov #define FUZZER_H_
16*5f6fd09aSAlexander Bulekov 
17*5f6fd09aSAlexander Bulekov #include "qemu/osdep.h"
18*5f6fd09aSAlexander Bulekov #include "qemu/units.h"
19*5f6fd09aSAlexander Bulekov #include "qapi/error.h"
20*5f6fd09aSAlexander Bulekov 
21*5f6fd09aSAlexander Bulekov #include "tests/qtest/libqtest.h"
22*5f6fd09aSAlexander Bulekov 
23*5f6fd09aSAlexander Bulekov /**
24*5f6fd09aSAlexander Bulekov  * A libfuzzer fuzzing target
25*5f6fd09aSAlexander Bulekov  *
26*5f6fd09aSAlexander Bulekov  * The QEMU fuzzing binary is built with all available targets, each
27*5f6fd09aSAlexander Bulekov  * with a unique @name that can be specified on the command-line to
28*5f6fd09aSAlexander Bulekov  * select which target should run.
29*5f6fd09aSAlexander Bulekov  *
30*5f6fd09aSAlexander Bulekov  * A target must implement ->fuzz() to process a random input.  If QEMU
31*5f6fd09aSAlexander Bulekov  * crashes in ->fuzz() then libfuzzer will record a failure.
32*5f6fd09aSAlexander Bulekov  *
33*5f6fd09aSAlexander Bulekov  * Fuzzing targets are registered with fuzz_add_target():
34*5f6fd09aSAlexander Bulekov  *
35*5f6fd09aSAlexander Bulekov  *   static const FuzzTarget fuzz_target = {
36*5f6fd09aSAlexander Bulekov  *       .name = "my-device-fifo",
37*5f6fd09aSAlexander Bulekov  *       .description = "Fuzz the FIFO buffer registers of my-device",
38*5f6fd09aSAlexander Bulekov  *       ...
39*5f6fd09aSAlexander Bulekov  *   };
40*5f6fd09aSAlexander Bulekov  *
41*5f6fd09aSAlexander Bulekov  *   static void register_fuzz_target(void)
42*5f6fd09aSAlexander Bulekov  *   {
43*5f6fd09aSAlexander Bulekov  *       fuzz_add_target(&fuzz_target);
44*5f6fd09aSAlexander Bulekov  *   }
45*5f6fd09aSAlexander Bulekov  *   fuzz_target_init(register_fuzz_target);
46*5f6fd09aSAlexander Bulekov  */
47*5f6fd09aSAlexander Bulekov typedef struct FuzzTarget {
48*5f6fd09aSAlexander Bulekov     const char *name;         /* target identifier (passed to --fuzz-target=)*/
49*5f6fd09aSAlexander Bulekov     const char *description;  /* help text */
50*5f6fd09aSAlexander Bulekov 
51*5f6fd09aSAlexander Bulekov 
52*5f6fd09aSAlexander Bulekov     /*
53*5f6fd09aSAlexander Bulekov      * returns the arg-list that is passed to qemu/softmmu init()
54*5f6fd09aSAlexander Bulekov      * Cannot be NULL
55*5f6fd09aSAlexander Bulekov      */
56*5f6fd09aSAlexander Bulekov     const char* (*get_init_cmdline)(struct FuzzTarget *);
57*5f6fd09aSAlexander Bulekov 
58*5f6fd09aSAlexander Bulekov     /*
59*5f6fd09aSAlexander Bulekov      * will run once, prior to running qemu/softmmu init.
60*5f6fd09aSAlexander Bulekov      * eg: set up shared-memory for communication with the child-process
61*5f6fd09aSAlexander Bulekov      * Can be NULL
62*5f6fd09aSAlexander Bulekov      */
63*5f6fd09aSAlexander Bulekov     void(*pre_vm_init)(void);
64*5f6fd09aSAlexander Bulekov 
65*5f6fd09aSAlexander Bulekov     /*
66*5f6fd09aSAlexander Bulekov      * will run once, after QEMU has been initialized, prior to the fuzz-loop.
67*5f6fd09aSAlexander Bulekov      * eg: detect the memory map
68*5f6fd09aSAlexander Bulekov      * Can be NULL
69*5f6fd09aSAlexander Bulekov      */
70*5f6fd09aSAlexander Bulekov     void(*pre_fuzz)(QTestState *);
71*5f6fd09aSAlexander Bulekov 
72*5f6fd09aSAlexander Bulekov     /*
73*5f6fd09aSAlexander Bulekov      * accepts and executes an input from libfuzzer. this is repeatedly
74*5f6fd09aSAlexander Bulekov      * executed during the fuzzing loop. Its should handle setup, input
75*5f6fd09aSAlexander Bulekov      * execution and cleanup.
76*5f6fd09aSAlexander Bulekov      * Cannot be NULL
77*5f6fd09aSAlexander Bulekov      */
78*5f6fd09aSAlexander Bulekov     void(*fuzz)(QTestState *, const unsigned char *, size_t);
79*5f6fd09aSAlexander Bulekov 
80*5f6fd09aSAlexander Bulekov } FuzzTarget;
81*5f6fd09aSAlexander Bulekov 
82*5f6fd09aSAlexander Bulekov void flush_events(QTestState *);
83*5f6fd09aSAlexander Bulekov void reboot(QTestState *);
84*5f6fd09aSAlexander Bulekov 
85*5f6fd09aSAlexander Bulekov /*
86*5f6fd09aSAlexander Bulekov  * makes a copy of *target and adds it to the target-list.
87*5f6fd09aSAlexander Bulekov  * i.e. fine to set up target on the caller's stack
88*5f6fd09aSAlexander Bulekov  */
89*5f6fd09aSAlexander Bulekov void fuzz_add_target(const FuzzTarget *target);
90*5f6fd09aSAlexander Bulekov 
91*5f6fd09aSAlexander Bulekov int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
92*5f6fd09aSAlexander Bulekov int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp);
93*5f6fd09aSAlexander Bulekov 
94*5f6fd09aSAlexander Bulekov #endif
95*5f6fd09aSAlexander Bulekov 
96