// fuzz_target.cc extern"C"intLLVMFuzzerTestOneInput(constuint8_t *Data, size_t Size){ DoSomethingInterestingWithMyAPI(Data, Size); return0; // Values other than 0 and -1 are reserved for future use. }
clang -g -O1 -fsanitize=fuzzer fuzz_target.cc # Builds the fuzz target w/o sanitizers clang -g -O1 -fsanitize=fuzzer,address fuzz_target.cc # Builds the fuzz target with ASAN clang -g -O1 -fsanitize=fuzzer,signed-integer-overflow fuzz_target.cc # Builds the fuzz target with a part of UBSAN clang -g -O1 -fsanitize=fuzzer,memory fuzz_target.cc # Builds the fuzz target with MSAN
% rm -f SomeLocalPath % ./my_fuzzer CORPUS1 CORPUS2 -merge=1 -merge_control_file=SomeLocalPath ... MERGE-INNER: using the control file 'SomeLocalPath' ... # While this is running, do `killall -SIGUSR1 my_fuzzer` in another console ==9015== INFO: libFuzzer: exiting as requested # This will leave the file SomeLocalPath with the partial state of the merge. # Now, you can continue the merge by executing the same command. The merge will continue from where it has been interrupted. % ./my_fuzzer CORPUS1 CORPUS2 -merge=1 -merge_control_file=SomeLocalPath ... MERGE-OUTER: non-empty control file provided: 'SomeLocalPath' MERGE-OUTER: control file ok, 32 files total, first not processed file 20 ...
// Copyright 2016 Google Inc. All Rights Reserved. // Licensed under the Apache License, Version 2.0 (the "License"); #include<stdint.h> #include<stdlib.h> #include<string> #include<arpa/nameser.h>
注意需要将原始脚本中的 -fsanitize-coverage=trace-pc-guard 替换为 -fsanitize=fuzzer,否则执行 Fuzz 时会出现错误:-fsanitize-coverage=trace-pc-guard is no longer supported by libFuzzer。
1 2 3 4
root@server:~/fuzz$ ./cares-fsanitize_fuzzer -fsanitize-coverage=trace-pc-guard is no longer supported by libFuzzer. Please either migrate to a compiler that supports -fsanitize=fuzzer or use an older version of libFuzzer
root@server:~/fuzz$ ./cares-fsanitize_fuzzer INFO: Seed: 817252946 INFO: Loaded 1 modules (10 inline 8-bit counters): 10 [0x5a90e0, 0x5a90ea), INFO: Loaded 1 PC tables (10 PCs): 10 [0x56c278,0x56c318), INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes INFO: A corpus is not provided, starting from an empty corpus #2 INITED cov: 3 ft: 3 corp: 1/1b exec/s: 0 rss: 27Mb #3 NEW cov: 4 ft: 4 corp: 2/5b lim: 4 exec/s: 0 rss: 27Mb L: 4/4 MS: 1 CrossOver- #10 REDUCE cov: 4 ft: 4 corp: 2/4b lim: 4 exec/s: 0 rss: 27Mb L: 3/3 MS: 2 ChangeByte-CrossOver- #11 REDUCE cov: 4 ft: 4 corp: 2/3b lim: 4 exec/s: 0 rss: 27Mb L: 2/2 MS: 1 EraseBytes- #1368 REDUCE cov: 6 ft: 6 corp: 3/20b lim: 17 exec/s: 0 rss: 27Mb L: 17/17 MS: 2 InsertByte-InsertRepeatedBytes- #1524 REDUCE cov: 6 ft: 6 corp: 3/19b lim: 17 exec/s: 0 rss: 27Mb L: 16/16 MS: 1 EraseBytes- ================================================================= ==3049145==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030012599c2 at pc 0x000000550e1c bp 0x7fffbad826d0 sp 0x7fffbad826c8 WRITE of size 1 at 0x6030012599c2 thread T0 #0 0x550e1b in ares_create_query (/home/fuzz/cares-fsanitize_fuzzer+0x550e1b) #1 0x55053c in LLVMFuzzerTestOneInput /home/fuzz/cares/target.cc:14:3 #2 0x4586a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fuzz/cares-fsanitize_fuzzer+0x4586a1) #3 0x457de5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/home/fuzz/cares-fsanitize_fuzzer+0x457de5) #4 0x45a087 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fuzz/cares-fsanitize_fuzzer+0x45a087) #5 0x45ad85 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/home/fuzz/cares-fsanitize_fuzzer+0x45ad85) #6 0x44973e in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fuzz/cares-fsanitize_fuzzer+0x44973e) #7 0x472582 in main (/home/fuzz/cares-fsanitize_fuzzer+0x472582) #8 0x7fd31481c082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) #9 0x41e4dd in _start (/home/fuzz/cares-fsanitize_fuzzer+0x41e4dd)
0x6030012599c2 is located 0 bytes to the right of 18-byte region [0x6030012599b0,0x6030012599c2) allocated by thread T0 here: #0 0x51e20d in malloc (/home/fuzz/cares-fsanitize_fuzzer+0x51e20d) #1 0x5508f6 in ares_create_query (/home/fuzz/cares-fsanitize_fuzzer+0x5508f6) #2 0x55053c in LLVMFuzzerTestOneInput /home/fuzz/cares/target.cc:14:3 #3 0x4586a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/fuzz/cares-fsanitize_fuzzer+0x4586a1) #4 0x457de5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/home/fuzz/cares-fsanitize_fuzzer+0x457de5) #5 0x45a087 in fuzzer::Fuzzer::MutateAndTestOne() (/home/fuzz/cares-fsanitize_fuzzer+0x45a087) #6 0x45ad85 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/home/fuzz/cares-fsanitize_fuzzer+0x45ad85) #7 0x44973e in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/fuzz/cares-fsanitize_fuzzer+0x44973e) #8 0x472582 in main (/home/fuzz/cares-fsanitize_fuzzer+0x472582) #9 0x7fd31481c082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/fuzz/cares-fsanitize_fuzzer+0x550e1b) in ares_create_query Shadow bytes around the buggy address: 0x0c06802432e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c06802432f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0680243300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0680243310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c0680243320: fa fa fa fa fa fa fa fa fa fa fd fd fd fa fa fa =>0x0c0680243330: fd fd fd fa fa fa 00 00[02]fa fa fa fd fd fd fa 0x0c0680243340: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd 0x0c0680243350: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa 0x0c0680243360: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa 0x0c0680243370: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd 0x0c0680243380: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==3049145==ABORTING MS: 4 ChangeByte-InsertByte-CopyPart-ChangeByte-; base unit: 00b28ff06b788b9b67c6b259800f404f9f3761fd 0x5c,0x2e,0x0,0x6b,0x0, \\.\x00k\x00 artifact_prefix='./'; Test unit written to ./crash-edef708d314ed627eba0ef2b042e47aa96a9b899 Base64: XC4AawA=
# Lines starting with '#' and empty lines are ignored. # Adds "blah" (w/o quotes) to the dictionary. kw1="blah" # Use \\ for backslash and \" for quotes. kw2="\"ac\\dc\"" # Use \xAB for hex values kw3="\xF7\xF8" # the name of the keyword followed by '=' may be omitted: "foo\x0Abar"
voidMyInitPRNG() { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION // In fuzzing mode the behavior of the code should be deterministic. srand(0); #else srand(time(0)); #endif }