blob: 1a25744d3c9930091c714ac0e9596400edfe6c86 [file] [log] [blame] [view]
Joe Gregorio02f72022021-03-27 10:12:45 -04001---
Joe Gregorioe296c562021-04-05 11:39:40 -04002title: 'Fuzzing'
3linkTitle: 'Fuzzing'
Joe Gregorio02f72022021-03-27 10:12:45 -04004---
5
Joe Gregorioe296c562021-04-05 11:39:40 -04006## Reproducing using `fuzz`
Joe Gregorio02f72022021-03-27 10:12:45 -04007
Joe Gregorioe296c562021-04-05 11:39:40 -04008We assume that you can [build Skia](/docs/user/build). Many fuzzes only
9reproduce when building with ASAN or MSAN; see
10[those instructions for more details](../xsan).
Joe Gregorio02f72022021-03-27 10:12:45 -040011
12When building, you should add the following args to BUILD.gn to make reproducing
13less machine- and platform- dependent:
14
15 skia_use_fontconfig=false
16 skia_use_freetype=true
17 skia_use_system_freetype2=false
18 skia_use_wuffs=true
19 skia_enable_skottie=true
20 skia_enable_fontmgr_custom_directory=false
21 skia_enable_fontmgr_custom_embedded=false
22 skia_enable_fontmgr_custom_empty=true
23
Joe Gregorioe296c562021-04-05 11:39:40 -040024All that is needed to reproduce a fuzz downloaded from ClusterFuzz or oss-fuzz
25is to run something like:
Joe Gregorio02f72022021-03-27 10:12:45 -040026
27 out/ASAN/fuzz -b /path/to/downloaded/testcase
28
29The fuzz binary will try its best to guess what the type/name should be based on
Joe Gregorioe296c562021-04-05 11:39:40 -040030the name of the testcase. Manually providing type and name is also supported,
31like:
Joe Gregorio02f72022021-03-27 10:12:45 -040032
33 out/ASAN/fuzz -t filter_fuzz -b /path/to/downloaded/testcase
34 out/ASAN/fuzz -t api -n RasterN32Canvas -b /path/to/downloaded/testcase
35
36To enumerate all supported types and names, run the following:
37
38 out/ASAN/fuzz --help # will list all types
39 out/ASAN/fuzz -t api # will list all names
40
41If the crash does not show up, try to add the flag --loops:
42
43 out/ASAN/fuzz -b /path/to/downloaded/testcase --loops <times-to-run>
44
Joe Gregorioe296c562021-04-05 11:39:40 -040045## Writing fuzzers with libfuzzer
Joe Gregorio02f72022021-03-27 10:12:45 -040046
47libfuzzer is an easy way to write new fuzzers, and how we run them on oss-fuzz.
48Your fuzzer entry point should implement this API:
49
50 extern "C" int LLVMFuzzerTestOneInput(const uint8_t*, size_t);
51
52First install Clang and libfuzzer, e.g.
53
54 sudo apt install clang-10 libc++-10-dev libfuzzer-10-dev
55
56You should now be able to use `-fsanitize=fuzzer` with Clang.
57
58Set up GN args to use libfuzzer:
59
60 cc = "clang-10"
61 cxx = "clang++-10"
62 sanitize = "fuzzer"
Kevin Lubick7cece5e2021-09-16 14:27:50 -040063 extra_cflags = [ "-DSK_BUILD_FOR_LIBFUZZER", # enables fuzzer-constraints (see below)
64 "-O1" # Or whatever you want.
65 ]
Joe Gregorio02f72022021-03-27 10:12:45 -040066 ...
67
68Build Skia and your fuzzer entry point:
69
70 ninja -C out/libfuzzer skia
71 clang++-10 -I. -O1 -fsanitize=fuzzer fuzz/oss_fuzz/whatever.cpp out/libfuzzer/libskia.a
72
73Run your new fuzzer binary
74
75 ./a.out
76
Joe Gregorioe296c562021-04-05 11:39:40 -040077## Fuzzing Defines
Joe Gregorio02f72022021-03-27 10:12:45 -040078
Joe Gregorioe296c562021-04-05 11:39:40 -040079There are some defines that can help guide a fuzzer to be more productive (e.g.
80avoid OOMs, avoid unnecessarily slow code).
Joe Gregorio02f72022021-03-27 10:12:45 -040081
82 // Required for fuzzing with afl-fuzz to prevent OOMs from adding noise.
83 SK_BUILD_FOR_AFL_FUZZ
84
85 // Required for fuzzing with libfuzzer
86 SK_BUILD_FOR_LIBFUZZER
87
88 // This define adds in guards to abort when we think some code path will take a long time or
89 // use a lot of RAM. It is set by default when either of the above defines are set.
90 SK_BUILD_FOR_FUZZER