@@ -10,8 +10,8 @@ n-core system, you can almost always run around n concurrent fuzzing jobs with
10
10
virtually no performance hit (you can use the afl-gotcpu tool to make sure).
11
11
12
12
In fact, if you rely on just a single job on a multi-core system, you will
13
- be underutilizing the hardware. So, parallelization is usually the right
14
- way to go.
13
+ be underutilizing the hardware. So, parallelization is always the right way to
14
+ go.
15
15
16
16
When targeting multiple unrelated binaries or using the tool in
17
17
"non-instrumented" (-n) mode, it is perfectly fine to just start up several
@@ -65,22 +65,7 @@ still perform deterministic checks; while the secondary instances will
65
65
proceed straight to random tweaks.
66
66
67
67
Note that you must always have one -M main instance!
68
-
69
- Note that running multiple -M instances is wasteful, although there is an
70
- experimental support for parallelizing the deterministic checks. To leverage
71
- that, you need to create -M instances like so:
72
-
73
- ```
74
- ./afl-fuzz -i testcase_dir -o sync_dir -M mainA:1/3 [...]
75
- ./afl-fuzz -i testcase_dir -o sync_dir -M mainB:2/3 [...]
76
- ./afl-fuzz -i testcase_dir -o sync_dir -M mainC:3/3 [...]
77
- ```
78
-
79
- ...where the first value after ':' is the sequential ID of a particular main
80
- instance (starting at 1), and the second value is the total number of fuzzers to
81
- distribute the deterministic fuzzing across. Note that if you boot up fewer
82
- fuzzers than indicated by the second number passed to -M, you may end up with
83
- poor coverage.
68
+ Running multiple -M instances is wasteful!
84
69
85
70
You can also monitor the progress of your jobs from the command line with the
86
71
provided afl-whatsup tool. When the instances are no longer finding new paths,
@@ -99,61 +84,88 @@ example may be:
99
84
This is not a concern if you use @@ without -f and let afl-fuzz come up with the
100
85
file name.
101
86
102
- ## 3) Syncing with non-afl fuzzers or independant instances
87
+ ## 3) Multiple -M mains
88
+
89
+
90
+ There is support for parallelizing the deterministic checks.
91
+ This is only needed where
92
+
93
+ 1 . many new paths are found fast over a long time and it looks unlikely that
94
+ main node will ever catch up, and
95
+ 2 . deterministic fuzzing is actively helping path discovery (you can see this
96
+ in the main node for the first for lines in the "fuzzing strategy yields"
97
+ section. If the ration ` found/attemps ` is high, then it is effective. It
98
+ most commonly isn't.)
99
+
100
+ Only if both are true it is beneficial to have more than one main.
101
+ You can leverage this by creating -M instances like so:
102
+
103
+ ```
104
+ ./afl-fuzz -i testcase_dir -o sync_dir -M mainA:1/3 [...]
105
+ ./afl-fuzz -i testcase_dir -o sync_dir -M mainB:2/3 [...]
106
+ ./afl-fuzz -i testcase_dir -o sync_dir -M mainC:3/3 [...]
107
+ ```
108
+
109
+ ... where the first value after ':' is the sequential ID of a particular main
110
+ instance (starting at 1), and the second value is the total number of fuzzers to
111
+ distribute the deterministic fuzzing across. Note that if you boot up fewer
112
+ fuzzers than indicated by the second number passed to -M, you may end up with
113
+ poor coverage.
114
+
115
+ ## 4) Syncing with non-afl fuzzers or independant instances
103
116
104
117
A -M main node can be told with the ` -F other_fuzzer_queue_directory ` option
105
118
to sync results from other fuzzers, e.g. libfuzzer or honggfuzz.
106
119
107
120
Only the specified directory will by synced into afl, not subdirectories.
108
- The specified directories do not need to exist yet at the start of afl.
121
+ The specified directory does not need to exist yet at the start of afl.
109
122
110
- ## 4) Multi-system parallelization
123
+ The ` -F ` option can be passed to the main node several times.
124
+
125
+ ## 5) Multi-system parallelization
111
126
112
127
The basic operating principle for multi-system parallelization is similar to
113
128
the mechanism explained in section 2. The key difference is that you need to
114
129
write a simple script that performs two actions:
115
130
116
131
- Uses SSH with authorized_keys to connect to every machine and retrieve
117
- a tar archive of the /path/to/sync_dir/<fuzzer_id>/queue/ directories for
118
- every <fuzzer_id> local to the machine. It's best to use a naming scheme
119
- that includes host name in the fuzzer ID, so that you can do something
120
- like:
132
+ a tar archive of the /path/to/sync_dir/<main_node(s)> directory local to
133
+ the machine.
134
+ It is best to use a naming scheme that includes host name and it's being
135
+ a main node (e.g. main1, main2) in the fuzzer ID, so that you can do
136
+ something like:
121
137
122
138
``` sh
123
- for s in {1..10} ; do
124
- ssh user@host ${s} " tar -czf - sync/host ${s} _fuzzid*/[qf]* " > host ${s} .tgz
139
+ for host in ` cat HOSTLIST ` ; do
140
+ ssh user@$host " tar -czf - sync/$host_main */ " > $host .tgz
125
141
done
126
142
```
127
143
128
144
- Distributes and unpacks these files on all the remaining machines, e.g.:
129
145
130
146
` ` ` sh
131
- for s in {1..10} ; do
132
- for d in {1..10} ; do
147
+ for srchost in ` cat HOSTLIST ` ; do
148
+ for dsthost in ` cat HOSTLIST ` ; do
133
149
test " $s " = " $d " && continue
134
- ssh user@host ${d} ' tar -kxzf -' < host ${s} .tgz
150
+ ssh user@$srchost ' tar -kxzf -' < $dsthost .tgz
135
151
done
136
152
done
137
153
` ` `
138
154
139
- There is an example of such a script in examples/distributed_fuzzing/;
140
- you can also find a more featured, experimental tool developed by
141
- Martijn Bogaard at:
142
-
143
- https://github.com/MartijnB/disfuzz-afl
144
-
145
- Another client-server implementation from Richo Healey is:
155
+ There is an example of such a script in examples/distributed_fuzzing/.
146
156
147
- https://github.com/richo/roving
157
+ There are other (older) more featured, experimental tools:
158
+ * https://github.com/richo/roving
159
+ * https://github.com/MartijnB/disfuzz-afl
148
160
149
- Note that these third-party tools are unsafe to run on systems exposed to the
150
- Internet or to untrusted users.
161
+ However these do not support syncing just main nodes (yet).
151
162
152
163
When developing custom test case sync code, there are several optimizations
153
164
to keep in mind:
154
165
155
166
- The synchronization does not have to happen very often; running the
156
- task every 30 minutes or so may be perfectly fine.
167
+ task every 60 minutes or even less often at later fuzzing stages is
168
+ fine
157
169
158
170
- There is no need to synchronize crashes/ or hangs/; you only need to
159
171
copy over queue/* (and ideally, also fuzzer_stats).
@@ -179,12 +191,17 @@ to keep in mind:
179
191
- You do not want a " main" instance of afl-fuzz on every system; you should
180
192
run them all with -S, and just designate a single process somewhere within
181
193
the fleet to run with -M.
194
+
195
+ - Syncing is only necessary for the main nodes on a system. It is possible
196
+ to run main-less with only secondaries. However then you need to find out
197
+ which secondary took over the temporary role to be the main node. Look for
198
+ the ` is_main` file in the fuzzer directories, eg. ` sync-dir/hostname-* /is_main`
182
199
183
200
It is * not* advisable to skip the synchronization script and run the fuzzers
184
201
directly on a network filesystem; unexpected latency and unkillable processes
185
202
in I/O wait state can mess things up.
186
203
187
- # # 5 ) Remote monitoring and data collection
204
+ # # 6 ) Remote monitoring and data collection
188
205
189
206
You can use screen, nohup, tmux, or something equivalent to run remote
190
207
instances of afl-fuzz. If you redirect the program' s output to a file, it will
@@ -208,7 +225,7 @@ Keep in mind that crashing inputs are *not* automatically propagated to the
208
225
main instance, so you may still want to monitor for crashes fleet-wide
209
226
from within your synchronization or health checking scripts (see afl-whatsup).
210
227
211
- # # 6 ) Asymmetric setups
228
+ # # 7 ) Asymmetric setups
212
229
213
230
It is perhaps worth noting that all of the following is permitted:
214
231
@@ -224,7 +241,7 @@ It is perhaps worth noting that all of the following is permitted:
224
241
the discovered test cases can have synergistic effects and improve the
225
242
overall coverage.
226
243
227
- (In this case, running one -M instance per each binary is a good plan .)
244
+ (In this case, running one -M instance per target is necessary .)
228
245
229
246
- Having some of the fuzzers invoke the binary in different ways.
230
247
For example, ' djpeg' supports several DCT modes, configurable with
0 commit comments