1cb93a386Sopenharmony_ci---
2cb93a386Sopenharmony_cititle: 'Fuzzing'
3cb93a386Sopenharmony_cilinkTitle: 'Fuzzing'
4cb93a386Sopenharmony_ci---
5cb93a386Sopenharmony_ci
6cb93a386Sopenharmony_ci## Reproducing using `fuzz`
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ciWe assume that you can [build Skia](/docs/user/build). Many fuzzes only
9cb93a386Sopenharmony_cireproduce when building with ASAN or MSAN; see
10cb93a386Sopenharmony_ci[those instructions for more details](../xsan).
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ciWhen building, you should add the following args to BUILD.gn to make reproducing
13cb93a386Sopenharmony_ciless machine- and platform- dependent:
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci    skia_use_fontconfig=false
16cb93a386Sopenharmony_ci    skia_use_freetype=true
17cb93a386Sopenharmony_ci    skia_use_system_freetype2=false
18cb93a386Sopenharmony_ci    skia_use_wuffs=true
19cb93a386Sopenharmony_ci    skia_enable_skottie=true
20cb93a386Sopenharmony_ci    skia_enable_fontmgr_custom_directory=false
21cb93a386Sopenharmony_ci    skia_enable_fontmgr_custom_embedded=false
22cb93a386Sopenharmony_ci    skia_enable_fontmgr_custom_empty=true
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciAll that is needed to reproduce a fuzz downloaded from ClusterFuzz or oss-fuzz
25cb93a386Sopenharmony_ciis to run something like:
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ci    out/ASAN/fuzz -b /path/to/downloaded/testcase
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ciThe fuzz binary will try its best to guess what the type/name should be based on
30cb93a386Sopenharmony_cithe name of the testcase. Manually providing type and name is also supported,
31cb93a386Sopenharmony_cilike:
32cb93a386Sopenharmony_ci
33cb93a386Sopenharmony_ci    out/ASAN/fuzz -t filter_fuzz -b /path/to/downloaded/testcase
34cb93a386Sopenharmony_ci    out/ASAN/fuzz -t api -n RasterN32Canvas -b /path/to/downloaded/testcase
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ciTo enumerate all supported types and names, run the following:
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci    out/ASAN/fuzz --help  # will list all types
39cb93a386Sopenharmony_ci    out/ASAN/fuzz -t api  # will list all names
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ciIf the crash does not show up, try to add the flag --loops:
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci    out/ASAN/fuzz -b /path/to/downloaded/testcase --loops <times-to-run>
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci## Writing fuzzers with libfuzzer
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_cilibfuzzer is an easy way to write new fuzzers, and how we run them on oss-fuzz.
48cb93a386Sopenharmony_ciYour fuzzer entry point should implement this API:
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    extern "C" int LLVMFuzzerTestOneInput(const uint8_t*, size_t);
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ciFirst install Clang and libfuzzer, e.g.
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    sudo apt install clang-10 libc++-10-dev libfuzzer-10-dev
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ciYou should now be able to use `-fsanitize=fuzzer` with Clang.
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ciSet up GN args to use libfuzzer:
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    cc = "clang-10"
61cb93a386Sopenharmony_ci    cxx = "clang++-10"
62cb93a386Sopenharmony_ci    sanitize = "fuzzer"
63cb93a386Sopenharmony_ci    extra_cflags = [ "-DSK_BUILD_FOR_LIBFUZZER", # enables fuzzer-constraints (see below)
64cb93a386Sopenharmony_ci                     "-O1"  # Or whatever you want.
65cb93a386Sopenharmony_ci                   ]
66cb93a386Sopenharmony_ci    ...
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ciBuild Skia and your fuzzer entry point:
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ci    ninja -C out/libfuzzer skia
71cb93a386Sopenharmony_ci    clang++-10 -I. -O1 -fsanitize=fuzzer fuzz/oss_fuzz/whatever.cpp out/libfuzzer/libskia.a
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_ciRun your new fuzzer binary
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci    ./a.out
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ci## Fuzzing Defines
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ciThere are some defines that can help guide a fuzzer to be more productive (e.g.
80cb93a386Sopenharmony_ciavoid OOMs, avoid unnecessarily slow code).
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    // Required for fuzzing with afl-fuzz to prevent OOMs from adding noise.
83cb93a386Sopenharmony_ci    SK_BUILD_FOR_AFL_FUZZ
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci    // Required for fuzzing with libfuzzer
86cb93a386Sopenharmony_ci    SK_BUILD_FOR_LIBFUZZER
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ci    // This define adds in guards to abort when we think some code path will take a long time or
89cb93a386Sopenharmony_ci    // use a lot of RAM. It is set by default when either of the above defines are set.
90cb93a386Sopenharmony_ci    SK_BUILD_FOR_FUZZER
91