1# Feedback-driven fuzzing #
2
3Honggfuzz (since its version 0.5) is capable of performing feedback-driven fuzzing. It utilizes Linux perf subsystem and hardware CPU counters to achieve the best outcomes.
4
5Developers can provide their own initial file (-f flag) which will be gradually improved upon. Alternatively, honggfuzz is capable of starting with just empty buffer, and work its way through, creating a valid fuzzing input in the process.
6
7# Requirements for software-based coverage-guided fuzzing (ASAN code coverage) #
8  * Clang 3.8/3.9/newer for compiling the fuzzed software (-fsanitize-coverage=bb)
9
10# Requirements for hardware-based coverage-guided fuzzing (counters, Intel BTS/PT) #
11  * GNU/Linux OS
12  * Relatively modern Linux kernel (v 3.2 should suffice)
13  * CPU which is supported by the [perf subsystem](https://perf.wiki.kernel.org/index.php/Main_Page) for hardware-assisted instruction and branch counting
14  * CPU supporting [BTS (Branch Trace Store)](https://software.intel.com/en-us/forums/topic/277868?language=en) for hardware assisted unique edge (branch pairs) counting. Currently it's available only in some newer Intel CPUs (unfortunately no AMD support for now)
15  * CPU supporting [Intel PT (Processor Tracing)](https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing) for hardware assisted unique edge (branch pairs) counting. Currently it's available only in some newer Intel CPUs (unfortunately no AMD support for now)
16
17# Examples #
18The fuzzing strategy is trying to identify files which add new code coverage (or increased instruction/branch counters). Then it adds such input files to the (dynamic) input corpus.
19
20There are always 2 phases of the fuzzing:
21 * 1) Honggfuzz goes through each file in the initial corpus (-f). It adds files which hit new code coverage to the dynamic input corpus (as well as saving them on the disk, using *COVERAGE_DATA.PID.<pid>.RND.<time>.<rnd>* pattern
22 * 2) Honggfuzz choses randomly files from the dynamic input corpus (in-memory), mutates them, and runs a new fuzzing task. If the newly created file adds to the code coverage, it gets added to the dynamic input corpus
23
24## ASAN Code coverage (-C)##
25```
26~/src/honggfuzz/honggfuzz -t20 -F 2800 -n3 -f IN/ -r 0.001 -C -q -- ./xmllint --format --nonet ___FILE___
27============================== STAT ==============================
28Iterations: 1419
29Start time: 2016-03-15 16:43:57 (16 seconds elapsed)
30Input file/dir: 'IN/'
31Fuzzed cmd: './xmllint --format --nonet ___FILE___'
32Fuzzing threads: 3
33Execs per second: 41 (avg: 88)
34Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
35Timeouts: 0
36Number of dynamic files: 251
37Coverage (max):
38  - total hit #bb:  8634 (coverage 11%)
39  - total #dso:     1 (instrumented only)
40  - discovered #bb: 1 (new from input seed)
41  - crashes:        0
42============================== LOGS ==============================
43[2016-03-15T16:49:00+0100][I][2094] fuzz_sanCovFeedback():463 SanCov Update: file size (Cur): 2141, newBBs:9, counters (Cur,New): 8569/1,1666/1
44
45```
46
47## Unique branch points counting (--linux_perf_bts_block) / Unique branch pair (edges) counting (--linux_perf_bts_edge) with Intel BTS, and unique branch points counting (--linux_perf_ipt_block) with Intel PT ##
48This is the most powerfull mode of feedback-driven counting that honggfuzz supports. It utilizes Intel's BTS (Branch Trace Store) feature to record all branch events (edges) inside the fuzzed process. Later, honggfuzz will de-duplicate those entries. The resulting number of branch pairs (edges) is good approximation of how much code of a given tool have been actively executed/used (code coverage).
49
50```
51$ honggfuzz --linux_perf_bts_block -f CURRENT_BEST -F 2500 -q -n1 -- /usr/bin/xmllint -format ___FILE___
52============================== STAT ==============================
53Iterations: 0
54Start time: 2016-02-16 18:35:32 (0 seconds elapsed)
55Input file/dir: 'CURRENT_BEST'
56Fuzzed cmd: '/usr/bin/xmllint -format ___FILE___'
57Fuzzing threads: 1
58Execs per second: 0 (avg: 0)
59Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
60Timeouts: 0
61Dynamic file size: 1 (max: 2500)
62Dynamic file max iterations keep for chosen seed (8193/8192)
63Coverage (max):
64  - BTS unique blocks: 0
65============================== LOGS ==============================
66[2016-02-16T18:35:32+0100][I][14846] fuzz_perfFeedback():420 New: (Size New,Old): 257,257, Perf (Cur,New): 0/0/0/0/0/0,0/0/2030/0/0/0
67[2016-02-16T18:35:32+0100][I][14846] fuzz_perfFeedback():420 New: (Size New,Old): 257,257, Perf (Cur,New): 0/0/2030/0/0/0,0/0/2031/0/0/0
68
69$ honggfuzz --linux_perf_bts_edge -f CURRENT_BEST -F 2500 -q -n1 -- /usr/bin/xmllint -format ___FILE___
70============================== STAT ==============================
71Iterations: 1
72Start time: 2016-02-16 18:37:08 (1 seconds elapsed)
73Input file/dir: 'CURRENT_BEST'
74Fuzzed cmd: '/usr/bin/xmllint -format ___FILE___'
75Fuzzing threads: 1
76Execs per second: 1 (avg: 1)
77Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
78Timeouts: 0
79Dynamic file size: 257 (max: 2500)
80Dynamic file max iterations keep for chosen seed (0/8192)
81Coverage (max):
82  - BTS unique edges:   0
83============================== LOGS ==============================
84[2016-02-16T18:37:09+0100][I][14944] fuzz_perfFeedback():420 New: (Size New,Old): 257,257, Perf (Cur,New): 0/0/0/0/0/0,0/0/0/2341/0/0
85
86$ honggfuzz --linux_perf_ipt_block -f CURRENT_BEST -F 2500 -q -n1 -- /usr/bin/xmllint -format ___FILE___
87============================== STAT ==============================
88Iterations: 0
89Start time: 2016-02-16 18:38:45 (0 seconds elapsed)
90Input file/dir: 'CURRENT_BEST'
91Fuzzed cmd: '/usr/bin/xmllint -format ___FILE___'
92Fuzzing threads: 1
93Execs per second: 0 (avg: 0)
94Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
95Timeouts: 0
96Dynamic file size: 1 (max: 2500)
97Dynamic file max iterations keep for chosen seed (8193/8192)
98Coverage (max):
99  - PT unique blocks: 243
100============================== LOGS ==============================
101```
102
103## Instruction counting (--linux_perf_instr) ##
104
105```
106============================== STAT ==============================
107Iterations: 2776
108Start time: 2016-02-16 18:40:51 (3 seconds elapsed)
109Input file/dir: 'CURRENT_BEST'
110Fuzzed cmd: '/usr/bin/xmllint -format ___FILE___'
111Fuzzing threads: 1
112Execs per second: 922 (avg: 925)
113Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
114Timeouts: 0
115Dynamic file size: 2496 (max: 2500)
116Dynamic file max iterations keep for chosen seed (136/8192)
117Coverage (max):
118  - cpu instructions:      1369752
119============================== LOGS ==============================
120[2016-02-16T18:40:54+0100][I][17406] fuzz_perfFeedback():420 New: (Size New,Old): 2497,2496, Perf (Cur,New): 1369752/0/0/0/0/0,1371747/0/0/0/0/0
121[2016-02-16T18:40:54+0100][I][17406] fuzz_perfFeedback():420 New: (Size New,Old): 2497,2497, Perf (Cur,New): 1371747/0/0/0/0/0,1372273/0/0/0/0/0
122[2016-02-16T18:40:54+0100][I][17406] fuzz_perfFeedback():420 New: (Size New,Old): 2497,2497, Perf (Cur,New): 1372273/0/0/0/0/0,1372390/0/0/0/0/0
123[2016-02-16T18:40:54+0100][I][17406] fuzz_perfFeedback():420 New: (Size New,Old): 2497,2497, Perf (Cur,New): 1372390/0/0/0/0/0,1372793/0/0/0/0/0
124```
125
126It will start with some initial file (or with no file at all), and subsequent fuzzing iterations will try to maximize the number of instructions spent on parsing it.
127
128## Branch counting (--linux_perf_branch) ##
129
130As above, it will try to maximize the number of branches taken by CPU on behalf of the fuzzed process (here: djpeg.static) while performing the fuzzing process.
131
132```
133$ honggfuzz --linux_perf_branch -f CURRENT_BEST -F 2500 -q -n1 -- /usr/bin/xmllint -format ___FILE___
134============================== STAT ==============================
135Iterations: 0
136Start time: 2016-02-16 18:39:41 (0 seconds elapsed)
137Input file/dir: 'CURRENT_BEST'
138Fuzzed cmd: '/usr/bin/xmllint -format ___FILE___'
139Fuzzing threads: 1
140Execs per second: 0 (avg: 0)
141Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
142Timeouts: 0
143Dynamic file size: 1 (max: 2500)
144Dynamic file max iterations keep for chosen seed (8193/8192)
145Coverage (max):
146  - cpu branches:          0
147============================== LOGS ==============================
148[2016-02-16T18:39:41+0100][I][16738] fuzz_perfFeedback():420 New: (Size New,Old): 2500,2500, Perf (Cur,New): 0/0/0/0/0/0,0/258259/0/0/0/0
149[2016-02-16T18:39:41+0100][I][16738] fuzz_perfFeedback():420 New: (Size New,Old): 2500,2500, Perf (Cur,New): 0/258259/0/0/0/0,0/258260/0/0/0/0
150[2016-02-16T18:39:41+0100][I][16738] fuzz_perfFeedback():420 New: (Size New,Old): 2500,2500, Perf (Cur,New): 0/258260/0/0/0/0,0/258261/0/0/0/0
151[2016-02-16T18:39:41+0100][I][16738] fuzz_perfFeedback():420 New: (Size New,Old): 2500,2500, Perf (Cur,New): 0/258261/0/0/0/0,0/258263/0/0/0/0
152```
153