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