Skip to content

Commit 6d364dd

Browse files
committed
add sancov-like allow/denylist instrument feature
1 parent 8ed6207 commit 6d364dd

16 files changed

+567
-323
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ anything below 9 is not recommended.
246246
+--------------------------------+
247247
| if you want to instrument only | -> use afl-gcc-fast and afl-gcc-fast++
248248
| parts of the target | see [gcc_plugin/README.md](gcc_plugin/README.md) and
249-
+--------------------------------+ [gcc_plugin/README.instrument_file.md](gcc_plugin/README.instrument_file.md)
249+
+--------------------------------+ [gcc_plugin/README.instrument_list.md](gcc_plugin/README.instrument_list.md)
250250
|
251251
| if not, or if you do not have a gcc with plugin support
252252
|
@@ -290,12 +290,18 @@ selectively only instrument parts of the target that you are interested in:
290290
create a file with all the filenames of the source code that should be
291291
instrumented.
292292
For afl-clang-lto and afl-gcc-fast - or afl-clang-fast if either the clang
293-
version is < 7 or the CLASSIC instrumentation is used - just put one
294-
filename per line, no directory information necessary, and set
295-
`export AFL_LLVM_INSTRUMENT_FILE=yourfile.txt`
296-
see [llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md)
293+
version is below 7 or the CLASSIC instrumentation is used - just put one
294+
filename or function per line (no directory information necessary for
295+
filenames9, and either set `export AFL_LLVM_ALLOWLIST=allowlist.txt` **or**
296+
`export AFL_LLVM_DENYLIST=denylist.txt` - depending on if you want per
297+
default to instrument unless noted (DENYLIST) or not perform instrumentation
298+
unless requested (ALLOWLIST).
299+
**NOTE:** In optimization functions might be inlined and then not match!
300+
see [llvm_mode/README.instrument_list.md](llvm_mode/README.instrument_list.md)
297301
For afl-clang-fast > 6.0 or if PCGUARD instrumentation is used then use the
298302
llvm sancov allow-list feature: [http://clang.llvm.org/docs/SanitizerCoverage.html](http://clang.llvm.org/docs/SanitizerCoverage.html)
303+
The llvm sancov format works with the allowlist/denylist feature of afl++
304+
however afl++ is more flexible in the format.
299305

300306
There are many more options and modes available however these are most of the
301307
time less effective. See:

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
## Roadmap 2.67+
44

5-
- expand on AFL_LLVM_INSTRUMENT_FILE to also support sancov allowlist format
65
- AFL_MAP_SIZE for qemu_mode and unicorn_mode
76
- CPU affinity for many cores? There seems to be an issue > 96 cores
87

docs/Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ sending a mail to <[email protected]>.
2222
- fixed a bug in redqueen for strings
2323
- llvm_mode:
2424
- now supports llvm 12!
25+
- support for AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST (previous
26+
AFL_LLVM_WHITELIST and AFL_LLVM_INSTRUMENT_FILE are deprecated and
27+
are matched to AFL_LLVM_ALLOWLIST). The format is compatible to llvm
28+
sancov, and also supports function matching!
2529
- fixes for laf-intel float splitting (thanks to mark-griffin for
2630
reporting)
2731
- LTO: autodictionary mode is a default

docs/FAQ.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation!
117117
Identify which source code files contain the functions that you need to
118118
remove from instrumentation.
119119

120-
Simply follow this document on how to do this: [llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md)
120+
Simply follow this document on how to do this: [llvm_mode/README.instrument_list.md](llvm_mode/README.instrument_list.md)
121121
If PCGUARD is used, then you need to follow this guide (needs llvm 12+!):
122122
[http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation](http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation)
123123

docs/env_variables.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,15 @@ Then there are a few specific features that are only available in llvm_mode:
202202

203203
See llvm_mode/README.laf-intel.md for more information.
204204

205-
### INSTRUMENT_FILE
205+
### INSTRUMENT LIST (selectively instrument files and functions)
206206

207207
This feature allows selectively instrumentation of the source
208208

209-
- Setting AFL_LLVM_INSTRUMENT_FILE with a filename will only instrument those
210-
files that match the names listed in this file.
209+
- Setting AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST with a filenames and/or
210+
function will only instrument (or skip) those files that match the names
211+
listed in the specified file.
211212

212-
See llvm_mode/README.instrument_file.md for more information.
213+
See llvm_mode/README.instrument_list.md for more information.
213214

214215
### NOT_ZERO
215216

@@ -241,7 +242,7 @@ Then there are a few specific features that are only available in the gcc_plugin
241242
- Setting AFL_GCC_INSTRUMENT_FILE with a filename will only instrument those
242243
files that match the names listed in this file (one filename per line).
243244

244-
See gcc_plugin/README.instrument_file.md for more information.
245+
See gcc_plugin/README.instrument_list.md for more information.
245246

246247
## 3) Settings for afl-fuzz
247248

docs/perf_tips.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ to get to the important parts in the code.
6767

6868
If you are only interested in specific parts of the code being fuzzed, you can
6969
instrument_files the files that are actually relevant. This improves the speed and
70-
accuracy of afl. See llvm_mode/README.instrument_file.md
70+
accuracy of afl. See llvm_mode/README.instrument_list.md
7171

7272
Also use the InsTrim mode on larger binaries, this improves performance and
7373
coverage a lot.

gcc_plugin/GNUmakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ install: all
163163
install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH)
164164
install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH)
165165
install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md
166-
install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md
166+
install -m 644 -T README.instrument_list.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md
167167

168168
clean:
169169
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2

gcc_plugin/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ install: all
152152
install -m 755 ../afl-gcc-fast $${DESTDIR}$(BIN_PATH)
153153
install -m 755 ../afl-gcc-pass.so ../afl-gcc-rt.o $${DESTDIR}$(HELPER_PATH)
154154
install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md
155-
install -m 644 -T README.instrument_file.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md
155+
install -m 644 -T README.instrument_list.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.instrument_file.md
156156

157157
clean:
158158
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 .test2

include/envs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ static char *afl_environment_variables[] = {
6262
"AFL_REAL_LD",
6363
"AFL_LD_PRELOAD",
6464
"AFL_LD_VERBOSE",
65+
"AFL_LLVM_ALLOWLIST",
66+
"AFL_LLVM_DENYLIST",
67+
"AFL_LLVM_BLOCKLIST",
6568
"AFL_LLVM_CMPLOG",
6669
"AFL_LLVM_INSTRIM",
6770
"AFL_LLVM_CTX",

llvm_mode/README.instrument_file.md

Lines changed: 0 additions & 81 deletions
This file was deleted.

llvm_mode/README.instrument_list.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Using afl++ with partial instrumentation
2+
3+
This file describes how you can selectively instrument only the source files
4+
or functions that are interesting to you using the LLVM instrumentation
5+
provided by afl++
6+
7+
## 1) Description and purpose
8+
9+
When building and testing complex programs where only a part of the program is
10+
the fuzzing target, it often helps to only instrument the necessary parts of
11+
the program, leaving the rest uninstrumented. This helps to focus the fuzzer
12+
on the important parts of the program, avoiding undesired noise and
13+
disturbance by uninteresting code being exercised.
14+
15+
For this purpose, a "partial instrumentation" support en par with llvm sancov
16+
is provided by afl++ that allows you to specify on a source file and function
17+
level which should be compiled with or without instrumentation.
18+
19+
Note: When using PCGUARD mode - and have llvm 12+ - you can use this instead:
20+
https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation
21+
22+
the llvm sancov list format is fully supported by afl++, however afl++ has
23+
more flexbility.
24+
25+
## 2) Building the LLVM module
26+
27+
The new code is part of the existing afl++ LLVM module in the llvm_mode/
28+
subdirectory. There is nothing specifically to do :)
29+
30+
## 3) How to use the partial instrumentation mode
31+
32+
In order to build with partial instrumentation, you need to build with
33+
afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++.
34+
The only required change is that you need to set either the environment variable
35+
AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST set with a filename.
36+
37+
That file then contains the filenames or functions that should be instrumented
38+
(AFL_LLVM_ALLOWLIST) or should specifically NOT instrumentd (AFL_LLVM_DENYLIST).
39+
40+
For matching, the function/filename that is being compiled must end in the
41+
function/filename entry contained in this the instrument file list (to avoid
42+
breaking the matching when absolute paths are used during compilation).
43+
44+
**NOTE:** In optimization functions might be inlined and then not match!
45+
46+
For example if your source tree looks like this:
47+
```
48+
project/
49+
project/feature_a/a1.cpp
50+
project/feature_a/a2.cpp
51+
project/feature_b/b1.cpp
52+
project/feature_b/b2.cpp
53+
```
54+
55+
and you only want to test feature_a, then create a the instrument file list file containing:
56+
```
57+
feature_a/a1.cpp
58+
feature_a/a2.cpp
59+
```
60+
61+
However if the instrument file list file contains only this, it works as well:
62+
```
63+
a1.cpp
64+
a2.cpp
65+
```
66+
but it might lead to files being unwantedly instrumented if the same filename
67+
exists somewhere else in the project directories.
68+
69+
You can also specify function names. Note that for C++ the function names
70+
must be mangled to match!
71+
72+
afl++ is intelligent to identify if an entry is a filename or a function.
73+
However if you want to be sure (and compliant to the sancov allow/blocklist
74+
format), you can file entries like this:
75+
```
76+
src: *malloc.c
77+
```
78+
and function entries like this:
79+
```
80+
fun: MallocFoo
81+
```
82+
Note that whitespace is ignored and comments (`# foo`) supported.
83+
84+
## 4) UNIX-style pattern matching
85+
You can add UNIX-style pattern matching in the the instrument file list entries.
86+
See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.

llvm_mode/README.lto.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,12 @@ make install
108108

109109
Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc.
110110

111-
Also the instrument file listing (AFL_LLVM_INSTRUMENT_FILE -> [README.instrument_file.md](README.instrument_file.md)) and
111+
Also the instrument file listing (AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST -> [README.instrument_list.md](README.instrument_list.md)) and
112112
laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work.
113-
InsTrim (control flow graph instrumentation) is supported and recommended!
114-
(set `AFL_LLVM_INSTRUMENT=CFG`)
115113

116114
Example:
117115
```
118116
CC=afl-clang-lto CXX=afl-clang-lto++ RANLIB=llvm-ranlib AR=llvm-ar ./configure
119-
export AFL_LLVM_INSTRUMENT=CFG
120117
make
121118
```
122119

llvm_mode/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Several options are present to make llvm_mode faster or help it rearrange
109109
the code to make afl-fuzz path discovery easier.
110110

111111
If you need just to instrument specific parts of the code, you can the instrument file list
112-
which C/C++ files to actually instrument. See [README.instrument_file](README.instrument_file.md)
112+
which C/C++ files to actually instrument. See [README.instrument_list](README.instrument_list.md)
113113

114114
For splitting memcmp, strncmp, etc. please see [README.laf-intel](README.laf-intel.md)
115115

llvm_mode/afl-clang-fast.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
229229
if (lto_mode) {
230230

231231
if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
232-
getenv("AFL_LLVM_WHITELIST")) {
232+
getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
233+
getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) {
233234

234235
cc_params[cc_par_cnt++] = "-Xclang";
235236
cc_params[cc_par_cnt++] = "-load";
@@ -637,9 +638,13 @@ int main(int argc, char **argv, char **envp) {
637638

638639
}
639640

640-
if ((getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) &&
641+
if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
642+
getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
643+
getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) &&
641644
getenv("AFL_DONT_OPTIMIZE"))
642-
FATAL("AFL_LLVM_INSTRUMENT_FILE and AFL_DONT_OPTIMIZE cannot be combined");
645+
WARNF(
646+
"AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined "
647+
"for file matching, only function matching!");
643648

644649
if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
645650
getenv("INSTRIM_LIB")) {
@@ -787,15 +792,17 @@ int main(int argc, char **argv, char **envp) {
787792
#if LLVM_VERSION_MAJOR <= 6
788793
instrument_mode = INSTRUMENT_AFL;
789794
#else
790-
if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")) {
795+
if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
796+
getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
797+
getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) {
791798

792799
instrument_mode = INSTRUMENT_AFL;
793800
WARNF(
794801
"switching to classic instrumentation because "
795-
"AFL_LLVM_INSTRUMENT_FILE does not work with PCGUARD. Use "
796-
"-fsanitize-coverage-allowlist=allowlist.txt if you want to use "
797-
"PCGUARD. Requires llvm 12+. See "
798-
"https://clang.llvm.org/docs/"
802+
"AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use "
803+
"-fsanitize-coverage-allowlist=allowlist.txt or "
804+
"-fsanitize-coverage-blocklist=denylist.txt if you want to use "
805+
"PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ "
799806
"SanitizerCoverage.html#partially-disabling-instrumentation");
800807

801808
} else
@@ -846,11 +853,14 @@ int main(int argc, char **argv, char **envp) {
846853
"together");
847854

848855
if (instrument_mode == INSTRUMENT_PCGUARD &&
849-
(getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST")))
856+
(getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
857+
getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
858+
getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")))
850859
FATAL(
851860
"Instrumentation type PCGUARD does not support "
852-
"AFL_LLVM_INSTRUMENT_FILE! Use "
853-
"-fsanitize-coverage-allowlist=allowlist.txt instead (requires llvm "
861+
"AFL_LLVM_ALLOWLIST/DENYLIST! Use "
862+
"-fsanitize-coverage-allowlist=allowlist.txt or "
863+
"-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm "
854864
"12+), see "
855865
"https://clang.llvm.org/docs/"
856866
"SanitizerCoverage.html#partially-disabling-instrumentation");

0 commit comments

Comments
 (0)