Commit Graph

442 Commits

Author SHA1 Message Date
Matt Morehouse 4b82f61474 [libFuzzer] Use macro instead of __attribute__.
This should fix the Windows buildbot errors.
2021-03-12 14:36:57 -08:00
Jonas Paulsson 5908c7ca41 [libFuzzer] Add attribute noinline on Fuzzer::ExecuteCallback().
The inlining of this function needs to be disabled as it is part of the
inpsected stack traces. It's string representation will look different
depending on if it was inlined or not which will cause it's string comparison
to fail.

When it was inlined in only one of the two execution stacks,
minimize_two_crashes.test failed on SystemZ. For details see
https://bugs.llvm.org/show_bug.cgi?id=49152.

Reviewers: Ulrich Weigand, Matt Morehouse, Arthur Eubanks

Differential Revision: https://reviews.llvm.org/D97975
2021-03-11 21:05:22 -06:00
Aaron Green 6708186c91 [crt][fuzzer] Fix up various numeric conversions
Attempting to build a standalone libFuzzer in Fuchsia's default toolchain for the purpose of cross-compiling the unit tests  revealed a number of not-quite-proper type conversions. Fuchsia's toolchain include `-std=c++17` and `-Werror`, among others, leading to many errors like `-Wshorten-64-to-32`, `-Wimplicit-float-conversion`, etc.

Most of these have been addressed by simply making the conversion explicit with a `static_cast`. These typically fell into one of two categories: 1) conversions between types where high precision isn't critical, e.g. the "energy" calculations for `InputInfo`, and 2) conversions where the values will never reach the bits being truncated, e.g. `DftTimeInSeconds` is not going to exceed 136 years.

The major exception to this is the number of features: there are several places that treat features as `size_t`, and others as `uint32_t`. This change makes the decision to cap the features at 32 bits. The maximum value of a feature as produced by `TracePC::CollectFeatures` is roughly:
  (NumPCsInPCTables + ValueBitMap::kMapSizeInBits + ExtraCountersBegin() - ExtraCountersEnd() + log2(SIZE_MAX)) * 8

It's conceivable for extremely large targets and/or extra counters that this limit could be reached. This shouldn't break fuzzing, but it will cause certain features to collide and lower the fuzzers overall precision. To address this, this change adds a warning to TracePC::PrintModuleInfo about excessive feature size if it is detected, and recommends refactoring the fuzzer into several smaller ones.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D97992
2021-03-11 16:01:28 -08:00
Aaron Green 10993bf072 Bugfix for collecting features from very small DSOs.
During unit tests, it was observed that crafting an artificially small DSO could cause OOB memory to be accessed. This change fixes that (but again, the affected DSOs are unlikely to ever occur outside unit tests).

Reviewed By: morehouse, charco

Differential Revision: https://reviews.llvm.org/D94507
2021-02-17 13:04:49 -08:00
Marco Vanotti 0fe4701e51 Expand unit tests for fuzzer::Merger
This change adds additional unit tests for fuzzer::Merger::Parse and fuzzer::Merger::Merge in anticipation of additional changes to the merge control file format to support cross-process fuzzing.

It modifies the parameter handling of Merge slightly in order to make NewFeatures and NewCov consistent with NewFiles; namely, Merge *replaces* the contents of these output parameters rather than accumulating them (thereby fixing a buggy return value).

This is change 1 of (at least) 18 for cross-process fuzzing support.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D94506
2021-02-12 11:18:34 -08:00
Max Moroz 70de7e0d9a [compiler-rt] FuzzedDataProvider: Add PickValueInArray for std::array
This makes `PickValueInArray` work for `std::array<T, s>` (C++11). I've also tested the C++17 `std::array` (with compiler-deduced template parameters)

```
Author:
MarcoFalke <falke.marco@gmail.com>
```

Reviewed By: Dor1s

Differential Revision: https://reviews.llvm.org/D93412
2020-12-30 10:25:26 -08:00
Joe Pletcher f897e82bfd [fuzzer] Add Windows Visual C++ exception intercept
Adds a new option, `handle_winexcept` to try to intercept uncaught
Visual C++ exceptions on Windows. On Linux, such exceptions are handled
implicitly by `std::terminate()` raising `SIBABRT`. This option brings the
Windows behavior in line with Linux.

Unfortunately this exception code is intentionally undocumented, however
has remained stable for the last decade. More information can be found
here: https://devblogs.microsoft.com/oldnewthing/20100730-00/?p=13273

Reviewed By: morehouse, metzman

Differential Revision: https://reviews.llvm.org/D89755
2020-11-12 13:11:14 -08:00
Jim Lin 1bd433bdff [compiler-rt][NFC] Fix typo in comment 2020-11-02 13:05:03 +08:00
Petr Hosek 11efd002b1 [CMake] Avoid accidental C++ standard library dependency in sanitizers
While sanitizers don't use C++ standard library, we could still end
up accidentally including or linking it just by the virtue of using
the C++ compiler. Pass -nostdinc++ and -nostdlib++ to avoid these
accidental dependencies.

Reviewed By: smeenai, vitalybuka

Differential Revision: https://reviews.llvm.org/D88922
2020-10-31 02:37:38 -07:00
Petr Hosek 59d5031591 [CMake] Add -fno-rtti into tsan unittests
And some other NFC parts of D88922
2020-10-30 20:03:38 -07:00
Cameron Finucane 6777919d5a [libFuzzer] Remove InterruptHandler from Fuchsia implementation
As implemented, the `InterruptHandler` thread was spinning trying to
`select()` on a null "stdin", wasting a significant amount of CPU for no
benefit. As Fuchsia does not have a native concept of stdin (or POSIX
signals), this commit simply removes this feature entirely.

Reviewed By: aarongreen

Differential Revision: https://reviews.llvm.org/D89266
2020-10-29 00:02:31 -07:00
Max Moroz dc62d5ec97 [libFuzzer] Added -print_full_coverage flag.
-print_full_coverage=1 produces a detailed branch coverage dump when run on a single file.
Uses same infrastructure as -print_coverage flag, but prints all branches (regardless of coverage status) in an easy-to-parse format.
Usage: For internal use with machine learning fuzzing models which require detailed coverage information on seed files to generate mutations.

Differential Revision: https://reviews.llvm.org/D85928
2020-10-23 16:05:54 -07:00
David Carlier 53065c543f [Sanitizers] Remove OpenBSD support (new attempt)
- Fixing VS compiler and other cases settings this time.

Reviewers: dmajor, hans

Reviewed By: hans

Differential Revision: https://reviews.llvm.org/D89759
2020-10-20 11:16:09 +01:00
Evgenii Stepanov 7ecd60bb70 Revert "[Sanitizers] Remove OpenBSD support" + 1
Revert "Fix compiler-rt build on Windows after D89640"

This reverts commit a7acee89d6.
This reverts commit d09b08919c.

Reason: breaks Linux / x86_64 build.
2020-10-19 16:11:21 -07:00
David Carlier d09b08919c [Sanitizers] Remove OpenBSD support
- Removing unused and unusable code.

Reviewers: krytarowski

Reviewed By: krytarowski

Differential Revision: https://reviews.llvm.org/D89640
2020-10-18 14:57:07 +01:00
Petr Hosek 220de1f32a Revert "[CMake] Avoid accidental C++ standard library dependency in sanitizers"
This reverts commit 287c318690 which broke
sanitizer tests that use C++ standard library.
2020-10-14 18:44:09 -07:00
Petr Hosek 287c318690 [CMake] Avoid accidental C++ standard library dependency in sanitizers
While sanitizers don't use C++ standard library, we could still end
up accidentally including or linking it just by the virtue of using
the C++ compiler. Pass -nostdinc++ and -nostdlib++ to avoid these
accidental dependencies.

Differential Revision: https://reviews.llvm.org/D88922
2020-10-14 18:26:56 -07:00
Fangrui Song 1ef0e94d5b [compiler-rt] Suppress -Wunused-result due to ::write when _FORTIFY_SOURCE>0 in glibc
Noticed by Peter Foley.
In glibc, ::write is declared as __attribute__((__warn_unused_result__)) when __USE_FORTIFY_LEVEL is larger than 0.
2020-10-12 09:57:12 -07:00
Julian Lettner c56bb45e83 [fuzzer] Remove unused variable
`TempAutoDictionary` is never used.  Maybe a leftover of a previous
experiment?

Differential Revision: https://reviews.llvm.org/D88763
2020-10-02 16:21:53 -07:00
Matt Morehouse f3c2e0bcee [libFuzzer] Enable entropic by default.
Entropic has performed at least on par with vanilla scheduling on
Clusterfuzz, and has shown a slight coverage improvement on FuzzBench:
https://www.fuzzbench.com/reports/2020-08-31/index.html

Reviewed By: Dor1s

Differential Revision: https://reviews.llvm.org/D87476
2020-09-16 10:44:34 -07:00
mhl 66df98945e [libfuzzer] Reduce default verbosity when printing large mutation sequences
When using a custom mutator (e.g. thrift mutator, similar to LPM)
that calls back into libfuzzer's mutations via `LLVMFuzzerMutate`, the mutation
sequences needed to achieve new coverage can get prohibitively large.

Printing these large sequences has two downsides:

1) It makes the logs hard to understand for a human.
2) The performance cost slows down fuzzing.

In this patch I change the `PrintMutationSequence` function to take a max
number of entries, to achieve this goal. I also update `PrintStatusForNewUnit`
to default to printing only 10 entries, in the default verbosity level (1),
requiring the user to set verbosity to 2 if they want the full mutation
sequence.

For our use case, turning off verbosity is not an option, as that would also
disable `PrintStats()` which is very useful for infrastructure that analyzes
the logs in realtime. I imagine most users of libfuzzer always want those logs
in the default.

I built a fuzzer locally with this patch applied to libfuzzer.

When running with the default verbosity, I see logs like this:

    #65 NEW    cov: 4799 ft: 10443 corp: 41/1447Kb lim: 64000 exec/s: 1 rss: 575Mb L: 28658/62542 MS: 196 Custom-CrossOver-ChangeBit-EraseBytes-ChangeBit-ChangeBit-ChangeBit-CrossOver-ChangeBit-CrossOver- DE: "\xff\xff\xff\x0e"-"\xfe\xff\xff\x7f"-"\xfe\xff\xff\x7f"-"\x17\x00\x00\x00\x00\x00\x00\x00"-"\x00\x00\x00\xf9"-"\xff\xff\xff\xff"-"\xfa\xff\xff\xff"-"\xf7\xff\xff\xff"-"@\xff\xff\xff\xff\xff\xff\xff"-"E\x00"-
    #67 NEW    cov: 4810 ft: 10462 corp: 42/1486Kb lim: 64000 exec/s: 1 rss: 577Mb L: 39823/62542 MS: 135 Custom-CopyPart-ShuffleBytes-ShuffleBytes-ChangeBit-ChangeBinInt-EraseBytes-ChangeBit-ChangeBinInt-ChangeBit- DE: "\x01\x00\x00\x00\x00\x00\x01\xf1"-"\x00\x00\x00\x07"-"\x00\x0d"-"\xfd\xff\xff\xff"-"\xfe\xff\xff\xf4"-"\xe3\xff\xff\xff"-"\xff\xff\xff\xf1"-"\xea\xff\xff\xff"-"\x00\x00\x00\xfd"-"\x01\x00\x00\x05"-

Staring hard at the logs it's clear that the cap of 10 is applied.

When running with verbosity level 2, the logs look like the below:

    #66    NEW    cov: 4700 ft: 10188 corp: 37/1186Kb lim: 64000 exec/s: 2 rss: 509Mb L: 47616/61231 MS: 520 Custom-CopyPart-ChangeBinInt-ChangeBit-ChangeByte-EraseBytes-PersAutoDict-CopyPart-ShuffleBytes-ChangeBit-ShuffleBytes-CopyPart-EraseBytes-CopyPart-ChangeBinInt-CopyPart-ChangeByte-ShuffleBytes-ChangeBinInt-ShuffleBytes-ChangeBit-CMP-ShuffleBytes-ChangeBit-CrossOver-ChangeBinInt-ChangeByte-ShuffleBytes-CrossOver-EraseBytes-ChangeBinInt-InsertRepeatedBytes-PersAutoDict-InsertRepeatedBytes-InsertRepeatedBytes-CrossOver-ChangeByte-ShuffleBytes-CopyPart-ShuffleBytes-CopyPart-CrossOver-ChangeBit-ShuffleBytes-CrossOver-PersAutoDict-ChangeByte-ChangeBit-ShuffleBytes-CrossOver-ChangeByte-EraseBytes-CopyPart-ChangeBinInt-PersAutoDict-CrossOver-ShuffleBytes-CrossOver-CrossOver-EraseBytes-CrossOver-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-ChangeByte-EraseBytes-ShuffleBytes-ShuffleBytes-ChangeBit-EraseBytes-ChangeBinInt-ChangeBit-ChangeBinInt-CopyPart-EraseBytes-PersAutoDict-EraseBytes-CopyPart-ChangeBinInt-ChangeByte-CrossOver-ChangeBinInt-ShuffleBytes-PersAutoDict-PersAutoDict-ChangeBinInt-CopyPart-ChangeBinInt-CrossOver-ChangeBit-ChangeBinInt-CopyPart-ChangeByte-ChangeBit-CopyPart-CrossOver-ChangeByte-ChangeBit-ChangeByte-ShuffleBytes-CMP-ChangeBit-CopyPart-ChangeBit-ChangeByte-ChangeBinInt-PersAutoDict-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBit-ChangeBinInt-ChangeBinInt-PersAutoDict-ChangeBinInt-ChangeBinInt-ChangeByte-CopyPart-ShuffleBytes-ChangeByte-ChangeBit-ChangeByte-ChangeByte-EraseBytes-CrossOver-ChangeByte-ChangeByte-EraseBytes-EraseBytes-InsertRepeatedBytes-ShuffleBytes-CopyPart-CopyPart-ChangeBit-ShuffleBytes-PersAutoDict-ShuffleBytes-ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ChangeByte-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBit-EraseBytes-CopyPart-ChangeByte-CrossOver-EraseBytes-CrossOver-ChangeByte-ShuffleBytes-ChangeByte-ChangeBinInt-CrossOver-ChangeByte-InsertRepeatedBytes-InsertByte-ShuffleBytes-PersAutoDict-ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ShuffleBytes-CopyPart-ShuffleBytes-EraseBytes-ShuffleBytes-ShuffleBytes-CrossOver-ChangeBinInt-CopyPart-CopyPart-CopyPart-EraseBytes-EraseBytes-ChangeByte-ChangeBinInt-ShuffleBytes-CMP-InsertByte-EraseBytes-ShuffleBytes-CopyPart-ChangeBit-CrossOver-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-EraseBytes-ChangeByte-ChangeBinInt-ChangeBit-ChangeBit-ChangeByte-ShuffleBytes-PersAutoDict-PersAutoDict-CMP-ChangeBit-ShuffleBytes-PersAutoDict-ChangeBinInt-EraseBytes-EraseBytes-ShuffleBytes-ChangeByte-ShuffleBytes-ChangeBit-EraseBytes-CMP-ShuffleBytes-ChangeByte-ChangeBinInt-EraseBytes-ChangeBinInt-ChangeByte-EraseBytes-ChangeByte-CrossOver-ShuffleBytes-EraseBytes-EraseBytes-ShuffleBytes-ChangeBit-EraseBytes-CopyPart-ShuffleBytes-ShuffleBytes-CrossOver-CopyPart-ChangeBinInt-ShuffleBytes-CrossOver-InsertByte-InsertByte-ChangeBinInt-ChangeBinInt-CopyPart-EraseBytes-ShuffleBytes-ChangeBit-ChangeBit-EraseBytes-ChangeByte-ChangeByte-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBinInt-ShuffleBytes-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-ShuffleBytes-CrossOver-EraseBytes-CopyPart-CopyPart-CopyPart-ChangeBit-ShuffleBytes-ChangeByte-EraseBytes-ChangeByte-InsertRepeatedBytes-InsertByte-InsertRepeatedBytes-PersAutoDict-EraseBytes-ShuffleBytes-ChangeByte-ShuffleBytes-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeBit-CrossOver-CrossOver-ShuffleBytes-CrossOver-CopyPart-CrossOver-CrossOver-CopyPart-ChangeByte-ChangeByte-CrossOver-ChangeBit-ChangeBinInt-EraseBytes-ShuffleBytes-EraseBytes-CMP-PersAutoDict-PersAutoDict-InsertByte-ChangeBit-ChangeByte-CopyPart-CrossOver-ChangeByte-ChangeBit-ChangeByte-CopyPart-ChangeBinInt-EraseBytes-CrossOver-ChangeBit-CrossOver-PersAutoDict-CrossOver-ChangeByte-CrossOver-ChangeByte-ChangeByte-CrossOver-ShuffleBytes-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-ChangeBinInt-ChangeBinInt-ChangeBinInt-ShuffleBytes-CrossOver-ChangeBinInt-ShuffleBytes-ChangeBit-PersAutoDict-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeByte-CrossOver-ChangeBit-CopyPart-ChangeBit-ChangeBit-CopyPart-ChangeByte-PersAutoDict-ChangeBit-ShuffleBytes-ChangeByte-ChangeBit-CrossOver-ChangeByte-CrossOver-ChangeByte-CrossOver-ChangeBit-ChangeByte-ChangeBinInt-PersAutoDict-CopyPart-ChangeBinInt-ChangeBit-CrossOver-ChangeBit-PersAutoDict-ShuffleBytes-EraseBytes-CrossOver-ChangeByte-ChangeBinInt-ShuffleBytes-ChangeBinInt-InsertRepeatedBytes-PersAutoDict-CrossOver-ChangeByte-Custom-PersAutoDict-CopyPart-CopyPart-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeBit-ShuffleBytes-CrossOver-CMP-ChangeByte-CopyPart-ShuffleBytes-CopyPart-CopyPart-CrossOver-CrossOver-CrossOver-ShuffleBytes-ChangeByte-ChangeBinInt-ChangeBit-ChangeBit-ChangeBit-ChangeByte-EraseBytes-ChangeByte-ChangeBit-ChangeByte-ChangeByte-CopyPart-PersAutoDict-ChangeBinInt-PersAutoDict-PersAutoDict-PersAutoDict-CopyPart-CopyPart-CrossOver-ChangeByte-ChangeBinInt-ShuffleBytes-ChangeBit-CopyPart-EraseBytes-CopyPart-CopyPart-CrossOver-ChangeByte-EraseBytes-ShuffleBytes-ChangeByte-CopyPart-EraseBytes-CopyPart-CrossOver-ChangeBinInt-ChangeBinInt-InsertByte-ChangeBinInt-ChangeBit-ChangeByte-CopyPart-ChangeByte-EraseBytes-ChangeByte-ChangeBit-ChangeByte-ShuffleBytes-CopyPart-ChangeBinInt-EraseBytes-CrossOver-ChangeBit-ChangeBit-CrossOver-EraseBytes-ChangeBinInt-CopyPart-CopyPart-ChangeBinInt-ChangeBit-EraseBytes-InsertRepeatedBytes-EraseBytes-ChangeBit-CrossOver-CrossOver-EraseBytes-EraseBytes-ChangeByte-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeBit-ChangeByte-EraseBytes-ChangeBit-ChangeByte-ChangeByte-CrossOver-CopyPart-EraseBytes-ChangeByte-EraseBytes-ChangeByte-ShuffleBytes-ShuffleBytes-ChangeByte-CopyPart-ChangeByte-ChangeByte-ChangeBit-CopyPart-ChangeBit-ChangeBinInt-CopyPart-ShuffleBytes-ChangeBit-ChangeBinInt-ChangeBit-EraseBytes-CMP-CrossOver-CopyPart-ChangeBinInt-CrossOver-CrossOver-CopyPart-CrossOver-CrossOver-InsertByte-InsertByte-CopyPart-Custom- DE: "warn"-"\x00\x00\x00\x80"-"\xfe\xff\xff\xfb"-"\xff\xff"-"\x10\x00\x00\x00"-"\xfe\xff\xff\xff"-"\xff\xff\xff\xf6"-"U\x01\x00\x00\x00\x00\x00\x00"-"\xd9\xff\xff\xff"-"\xfe\xff\xff\xea"-"\xf0\xff\xff\xff"-"\xfc\xff\xff\xff"-"warn"-"\xff\xff\xff\xff"-"\xfe\xff\xff\xfb"-"\x00\x00\x00\x80"-"\xfe\xff\xff\xf1"-"\xfe\xff\xff\xea"-"\x00\x00\x00\x00\x00\x00\x012"-"\xe2\x00"-"\xfb\xff\xff\xff"-"\x00\x00\x00\x00"-"\xe9\xff\xff\xff"-"\xff\xff"-"\x00\x00\x00\x80"-"\x01\x00\x04\xc9"-"\xf0\xff\xff\xff"-"\xf9\xff\xff\xff"-"\xff\xff\xff\xff\xff\xff\xff\x12"-"\xe2\x00"-"\xfe\xff\xff\xff"-"\xfe\xff\xff\xea"-"\xff\xff\xff\xff"-"\xf4\xff\xff\xff"-"\xe9\xff\xff\xff"-"\xf1\xff\xff\xff"-
    #48    NEW    cov: 4502 ft: 9151 corp: 27/750Kb lim: 64000 exec/s: 2 rss: 458Mb L: 50772/50772 MS: 259 ChangeByte-ShuffleBytes-ChangeBinInt-ChangeByte-ChangeByte-ChangeByte-ChangeByte-ChangeBit-CopyPart-CrossOver-CopyPart-ChangeByte-CrossOver-CopyPart-ChangeBit-ChangeByte-EraseBytes-ChangeByte-CopyPart-CopyPart-CopyPart-ChangeBit-EraseBytes-ChangeBinInt-CrossOver-CopyPart-CrossOver-CopyPart-ChangeBit-ChangeByte-ChangeBit-InsertByte-CrossOver-InsertRepeatedBytes-InsertRepeatedBytes-InsertRepeatedBytes-ChangeBinInt-EraseBytes-InsertRepeatedBytes-InsertByte-ChangeBit-ShuffleBytes-ChangeBit-ChangeBit-CopyPart-ChangeBit-ChangeByte-CrossOver-ChangeBinInt-ChangeByte-CrossOver-CMP-ChangeByte-CrossOver-ChangeByte-ShuffleBytes-ShuffleBytes-ChangeByte-ChangeBinInt-CopyPart-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-InsertByte-ChangeBit-CopyPart-ChangeBinInt-ChangeByte-CrossOver-ChangeBit-EraseBytes-CopyPart-ChangeBinInt-ChangeBit-ChangeBit-ChangeByte-CopyPart-ChangeBinInt-CrossOver-PersAutoDict-ChangeByte-ChangeBit-ChangeByte-ChangeBinInt-ChangeBinInt-EraseBytes-CopyPart-CopyPart-ChangeByte-ChangeByte-EraseBytes-PersAutoDict-CopyPart-ChangeByte-ChangeByte-EraseBytes-CrossOver-CopyPart-CopyPart-CopyPart-ChangeByte-ChangeBit-CMP-CopyPart-ChangeBinInt-ChangeBinInt-CrossOver-ChangeBit-ChangeBit-EraseBytes-ChangeByte-ShuffleBytes-ChangeBit-ChangeBinInt-CMP-InsertRepeatedBytes-CopyPart-Custom-ChangeByte-CrossOver-EraseBytes-ChangeBit-CopyPart-CrossOver-CMP-ShuffleBytes-EraseBytes-CrossOver-PersAutoDict-ChangeByte-CrossOver-CopyPart-CrossOver-CrossOver-ShuffleBytes-ChangeBinInt-CrossOver-ChangeBinInt-ShuffleBytes-PersAutoDict-ChangeByte-EraseBytes-ChangeBit-CrossOver-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-EraseBytes-InsertByte-InsertRepeatedBytes-InsertByte-InsertByte-ChangeByte-ChangeBinInt-ChangeBit-CrossOver-ChangeByte-CrossOver-EraseBytes-ChangeByte-ShuffleBytes-ChangeBit-ChangeBit-ShuffleBytes-CopyPart-ChangeByte-PersAutoDict-ChangeBit-ChangeByte-InsertRepeatedBytes-CMP-CrossOver-ChangeByte-EraseBytes-ShuffleBytes-CrossOver-ShuffleBytes-ChangeBinInt-ChangeBinInt-CopyPart-PersAutoDict-ShuffleBytes-ChangeBit-CopyPart-ShuffleBytes-CopyPart-EraseBytes-ChangeByte-ChangeBit-ChangeBit-ChangeBinInt-ChangeByte-CopyPart-EraseBytes-ChangeBinInt-EraseBytes-EraseBytes-PersAutoDict-CMP-PersAutoDict-CrossOver-CrossOver-ChangeBit-CrossOver-PersAutoDict-CrossOver-CopyPart-ChangeByte-EraseBytes-ChangeByte-ShuffleBytes-ChangeByte-ChangeByte-CrossOver-ChangeBit-EraseBytes-ChangeByte-EraseBytes-ChangeBinInt-CrossOver-CrossOver-EraseBytes-ChangeBinInt-CrossOver-ChangeBit-ShuffleBytes-ChangeBit-ChangeByte-EraseBytes-ChangeBit-CrossOver-CrossOver-CrossOver-ChangeByte-ChangeBit-ShuffleBytes-ChangeBit-ChangeBit-EraseBytes-CrossOver-CrossOver-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-CopyPart-CrossOver-CopyPart-CrossOver-CrossOver-EraseBytes-EraseBytes-ShuffleBytes-InsertRepeatedBytes-ChangeBit-CopyPart-Custom- DE: "\xfe\xff\xff\xfc"-"\x00\x00\x00\x00"-"F\x00"-"\xf3\xff\xff\xff"-"St9exception"-"_\x00\x00\x00"-"\xf6\xff\xff\xff"-"\xfe\xff\xff\xff"-"\x00\x00\x00\x00"-"p\x02\x00\x00\x00\x00\x00\x00"-"\xfe\xff\xff\xfb"-"\xff\xff"-"\xff\xff\xff\xff"-"\x01\x00\x00\x07"-"\xfe\xff\xff\xfe"-

These are prohibitively large and of limited value in the default case (when
someone is running the fuzzer, not debugging it), in my opinion.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D86658
2020-09-16 09:20:57 -07:00
Dokyung Song 1bb1eac6b1 [libFuzzer] Add a command-line option for tracing mutation of corpus inputs in the dot graph format.
This patch adds a new command-line option -mutation_graph_file=FILE for
debugging purposes, which traces how corpus inputs evolve during a fuzzing
run. For each new input that is added to the corpus, a new vertex corresponding
to the added input, as well as a new edge that connects its base input to itself
are written to the given file. Each vertex is labeled with the filename of the
input, and each edge is labeled with the mutation sequence that led to the input
w.r.t. its base input.

The format of the mutation graph file is the dot file format. Once prepended and
appended with "graph {" and "}", respectively, the graph becomes a valid dot
file and can be visualized.

Differential Revision: https://reviews.llvm.org/D86560
2020-09-09 03:28:53 +00:00
Hubert Tong dde16ef031 [tests][libFuzzer] Fix `-Wmissing-field-initializers` after D86092
Speculatively fix `-Werror,-Wmissing-field-initializers` failures
relating to the `ScalePerExecTime` field added by D86092.
2020-09-04 13:07:44 -04:00
Dokyung Song 5cda4dc7b4 [libFuzzer] Scale energy assigned to each input based on input execution time.
This patch scales the energy computed by the Entropic schedule based on the
execution time of each input. The input execution time is compared with the
average execution time of inputs in the corpus, and, based on the amount by
which they differ, the energy is scaled from 0.1x (for inputs executing slow) to
3x (for inputs executing fast). Note that the exact scaling criteria and formula
is borrowed from AFL.

On FuzzBench, this gives a sizeable throughput increase, which in turn leads to
more coverage on several benchmarks. For details, see the following report.

https://storage.googleapis.com/fuzzer-test-suite-public/exectime-report/index.html

Differential Revision: https://reviews.llvm.org/D86092
2020-09-03 20:38:20 +00:00
Dokyung Song b53243e194 [libFuzzer] Evenly select inputs to cross over with from the corpus regardless of the input's coverage.
This patch adds an option "cross_over_uniform_dist", which, if 1, considers all
inputs in the corpus for the crossover input selection. More specifically, this
patch uses a uniform distribution of all inputs in the corpus for the CrossOver
input selection. Note that input selection for mutation is still fully
determined by the scheduling policy (i.e., vanilla or Entropic); the uniform
distribution only applies to the secondary input selection, only for the
crossover mutation of the base input chosen by the scheduling policy. This way
the corpus inputs that have useful fragments in them, even though they are
deprioritized by the scheduling policy, have chances of getting mixed with other
inputs that are prioritized and selected as base input for mutation.

Differential Revision: https://reviews.llvm.org/D86954
2020-09-03 19:47:00 +00:00
Dokyung Song 62673c430d [libFuzzer] Add an option to keep initial seed inputs around.
This patch adds an option "keep_seed" to keep all initial seed inputs in the
corpus. Previously, only the initial seed inputs that find new coverage were
added to the corpus, and all the other initial inputs were discarded. We
observed in some circumstances that useful initial seed inputs are discarded as
they find no new coverage, even though they contain useful fragments in them
(e.g., SQLITE3 FuzzBench benchmark). This newly added option provides a way to
keeping seed inputs in the corpus for those circumstances. With this patch, and
with -keep_seed=1, all initial seed inputs are kept in the corpus regardless of
whether they find new coverage or not. Further, these seed inputs are not
replaced with smaller inputs even if -reduce_inputs=1.

Differential Revision: https://reviews.llvm.org/D86577
2020-09-03 15:54:39 +00:00
Matt Morehouse 711b980654 [fuzzer] Create user provided fuzzer writeable directories when requested if they dont exist
Currently, libFuzzer will exit with an error message if a non-existent
directory is provided for any of the appropriate arguments. For cases
where libFuzzer is used in a specialized embedded environment, it would
be much easier to have libFuzzer create the directories for the user.

This patch accommodates for this scenario by allowing the user to provide
the argument `-create_missing_dirs=1` which makes libFuzzer attempt to
create the `artifact_prefix`, `exact_artifact_path`,
`features_dir` and/or corpus directory if they don't already exist rather
than throw an error and exit.

Split off from D84808 as requested [here](https://reviews.llvm.org/D84808#2208546).

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D86733
2020-09-03 08:31:59 -07:00
Matt Morehouse 49dda4e58a [libFuzzer] Break dependency on common_interface_defs.h
Some libFuzzer users build using the build.sh script, without access to
the <sanitizer/common_interface_defs.h> include.

Update https://github.com/rust-fuzz/libfuzzer/issues/65.

Reviewed By: dokyungs

Differential Revision: https://reviews.llvm.org/D86981
2020-09-01 15:35:14 -07:00
Matt Morehouse 7139736261 Revert "[libfuzzer] Reduce default verbosity when printing large mutation sequences"
This reverts commit 2665425908 due to
buildbot failure.
2020-09-01 12:49:41 -07:00
Matt Morehouse 10670bdf54 Revert "[fuzzer] Create user provided fuzzer writeable directories when requested if they dont exist"
This reverts commit cb8912799d, since the
test fails on Windows.
2020-09-01 12:05:46 -07:00
Matt Morehouse cb8912799d [fuzzer] Create user provided fuzzer writeable directories when requested if they dont exist
Currently, libFuzzer will exit with an error message if a non-existent
directory is provided for any of the appropriate arguments. For cases
where libFuzzer is used in a specialized embedded environment, it would
be much easier to have libFuzzer create the directories for the user.

This patch accommodates for this scenario by allowing the user to provide
the argument `-create_missing_dirs=1` which makes libFuzzer attempt to
create the `artifact_prefix`, `exact_artifact_path`,
`features_dir` and/or corpus directory if they don't already exist rather
than throw an error and exit.

Split off from D84808 as requested [here](https://reviews.llvm.org/D84808#2208546).

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D86733
2020-09-01 11:50:47 -07:00
mhl 2665425908 [libfuzzer] Reduce default verbosity when printing large mutation sequences
When using a custom mutator (e.g. thrift mutator, similar to LPM)
that calls back into libfuzzer's mutations via `LLVMFuzzerMutate`, the mutation
sequences needed to achieve new coverage can get prohibitively large.

Printing these large sequences has two downsides:

1) It makes the logs hard to understand for a human.
2) The performance cost slows down fuzzing.

In this patch I change the `PrintMutationSequence` function to take a max
number of entries, to achieve this goal. I also update `PrintStatusForNewUnit`
to default to printing only 10 entries, in the default verbosity level (1),
requiring the user to set verbosity to 2 if they want the full mutation
sequence.

For our use case, turning off verbosity is not an option, as that would also
disable `PrintStats()` which is very useful for infrastructure that analyzes
the logs in realtime. I imagine most users of libfuzzer always want those logs
in the default.

I built a fuzzer locally with this patch applied to libfuzzer.

When running with the default verbosity, I see logs like this:

    #65 NEW    cov: 4799 ft: 10443 corp: 41/1447Kb lim: 64000 exec/s: 1 rss: 575Mb L: 28658/62542 MS: 196 Custom-CrossOver-ChangeBit-EraseBytes-ChangeBit-ChangeBit-ChangeBit-CrossOver-ChangeBit-CrossOver- DE: "\xff\xff\xff\x0e"-"\xfe\xff\xff\x7f"-"\xfe\xff\xff\x7f"-"\x17\x00\x00\x00\x00\x00\x00\x00"-"\x00\x00\x00\xf9"-"\xff\xff\xff\xff"-"\xfa\xff\xff\xff"-"\xf7\xff\xff\xff"-"@\xff\xff\xff\xff\xff\xff\xff"-"E\x00"-
    #67 NEW    cov: 4810 ft: 10462 corp: 42/1486Kb lim: 64000 exec/s: 1 rss: 577Mb L: 39823/62542 MS: 135 Custom-CopyPart-ShuffleBytes-ShuffleBytes-ChangeBit-ChangeBinInt-EraseBytes-ChangeBit-ChangeBinInt-ChangeBit- DE: "\x01\x00\x00\x00\x00\x00\x01\xf1"-"\x00\x00\x00\x07"-"\x00\x0d"-"\xfd\xff\xff\xff"-"\xfe\xff\xff\xf4"-"\xe3\xff\xff\xff"-"\xff\xff\xff\xf1"-"\xea\xff\xff\xff"-"\x00\x00\x00\xfd"-"\x01\x00\x00\x05"-

Staring hard at the logs it's clear that the cap of 10 is applied.

When running with verbosity level 2, the logs look like the below:

    #66    NEW    cov: 4700 ft: 10188 corp: 37/1186Kb lim: 64000 exec/s: 2 rss: 509Mb L: 47616/61231 MS: 520 Custom-CopyPart-ChangeBinInt-ChangeBit-ChangeByte-EraseBytes-PersAutoDict-CopyPart-ShuffleBytes-ChangeBit-ShuffleBytes-CopyPart-EraseBytes-CopyPart-ChangeBinInt-CopyPart-ChangeByte-ShuffleBytes-ChangeBinInt-ShuffleBytes-ChangeBit-CMP-ShuffleBytes-ChangeBit-CrossOver-ChangeBinInt-ChangeByte-ShuffleBytes-CrossOver-EraseBytes-ChangeBinInt-InsertRepeatedBytes-PersAutoDict-InsertRepeatedBytes-InsertRepeatedBytes-CrossOver-ChangeByte-ShuffleBytes-CopyPart-ShuffleBytes-CopyPart-CrossOver-ChangeBit-ShuffleBytes-CrossOver-PersAutoDict-ChangeByte-ChangeBit-ShuffleBytes-CrossOver-ChangeByte-EraseBytes-CopyPart-ChangeBinInt-PersAutoDict-CrossOver-ShuffleBytes-CrossOver-CrossOver-EraseBytes-CrossOver-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-ChangeByte-EraseBytes-ShuffleBytes-ShuffleBytes-ChangeBit-EraseBytes-ChangeBinInt-ChangeBit-ChangeBinInt-CopyPart-EraseBytes-PersAutoDict-EraseBytes-CopyPart-ChangeBinInt-ChangeByte-CrossOver-ChangeBinInt-ShuffleBytes-PersAutoDict-PersAutoDict-ChangeBinInt-CopyPart-ChangeBinInt-CrossOver-ChangeBit-ChangeBinInt-CopyPart-ChangeByte-ChangeBit-CopyPart-CrossOver-ChangeByte-ChangeBit-ChangeByte-ShuffleBytes-CMP-ChangeBit-CopyPart-ChangeBit-ChangeByte-ChangeBinInt-PersAutoDict-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBit-ChangeBinInt-ChangeBinInt-PersAutoDict-ChangeBinInt-ChangeBinInt-ChangeByte-CopyPart-ShuffleBytes-ChangeByte-ChangeBit-ChangeByte-ChangeByte-EraseBytes-CrossOver-ChangeByte-ChangeByte-EraseBytes-EraseBytes-InsertRepeatedBytes-ShuffleBytes-CopyPart-CopyPart-ChangeBit-ShuffleBytes-PersAutoDict-ShuffleBytes-ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ChangeByte-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBit-EraseBytes-CopyPart-ChangeByte-CrossOver-EraseBytes-CrossOver-ChangeByte-ShuffleBytes-ChangeByte-ChangeBinInt-CrossOver-ChangeByte-InsertRepeatedBytes-InsertByte-ShuffleBytes-PersAutoDict-ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ShuffleBytes-CopyPart-ShuffleBytes-EraseBytes-ShuffleBytes-ShuffleBytes-CrossOver-ChangeBinInt-CopyPart-CopyPart-CopyPart-EraseBytes-EraseBytes-ChangeByte-ChangeBinInt-ShuffleBytes-CMP-InsertByte-EraseBytes-ShuffleBytes-CopyPart-ChangeBit-CrossOver-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-EraseBytes-ChangeByte-ChangeBinInt-ChangeBit-ChangeBit-ChangeByte-ShuffleBytes-PersAutoDict-PersAutoDict-CMP-ChangeBit-ShuffleBytes-PersAutoDict-ChangeBinInt-EraseBytes-EraseBytes-ShuffleBytes-ChangeByte-ShuffleBytes-ChangeBit-EraseBytes-CMP-ShuffleBytes-ChangeByte-ChangeBinInt-EraseBytes-ChangeBinInt-ChangeByte-EraseBytes-ChangeByte-CrossOver-ShuffleBytes-EraseBytes-EraseBytes-ShuffleBytes-ChangeBit-EraseBytes-CopyPart-ShuffleBytes-ShuffleBytes-CrossOver-CopyPart-ChangeBinInt-ShuffleBytes-CrossOver-InsertByte-InsertByte-ChangeBinInt-ChangeBinInt-CopyPart-EraseBytes-ShuffleBytes-ChangeBit-ChangeBit-EraseBytes-ChangeByte-ChangeByte-ChangeBinInt-CrossOver-ChangeBinInt-ChangeBinInt-ShuffleBytes-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-ShuffleBytes-CrossOver-EraseBytes-CopyPart-CopyPart-CopyPart-ChangeBit-ShuffleBytes-ChangeByte-EraseBytes-ChangeByte-InsertRepeatedBytes-InsertByte-InsertRepeatedBytes-PersAutoDict-EraseBytes-ShuffleBytes-ChangeByte-ShuffleBytes-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeBit-CrossOver-CrossOver-ShuffleBytes-CrossOver-CopyPart-CrossOver-CrossOver-CopyPart-ChangeByte-ChangeByte-CrossOver-ChangeBit-ChangeBinInt-EraseBytes-ShuffleBytes-EraseBytes-CMP-PersAutoDict-PersAutoDict-InsertByte-ChangeBit-ChangeByte-CopyPart-CrossOver-ChangeByte-ChangeBit-ChangeByte-CopyPart-ChangeBinInt-EraseBytes-CrossOver-ChangeBit-CrossOver-PersAutoDict-CrossOver-ChangeByte-CrossOver-ChangeByte-ChangeByte-CrossOver-ShuffleBytes-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-ChangeBinInt-ChangeBinInt-ChangeBinInt-ChangeBinInt-ShuffleBytes-CrossOver-ChangeBinInt-ShuffleBytes-ChangeBit-PersAutoDict-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeByte-CrossOver-ChangeBit-CopyPart-ChangeBit-ChangeBit-CopyPart-ChangeByte-PersAutoDict-ChangeBit-ShuffleBytes-ChangeByte-ChangeBit-CrossOver-ChangeByte-CrossOver-ChangeByte-CrossOver-ChangeBit-ChangeByte-ChangeBinInt-PersAutoDict-CopyPart-ChangeBinInt-ChangeBit-CrossOver-ChangeBit-PersAutoDict-ShuffleBytes-EraseBytes-CrossOver-ChangeByte-ChangeBinInt-ShuffleBytes-ChangeBinInt-InsertRepeatedBytes-PersAutoDict-CrossOver-ChangeByte-Custom-PersAutoDict-CopyPart-CopyPart-ChangeBinInt-ShuffleBytes-ChangeBinInt-ChangeBit-ShuffleBytes-CrossOver-CMP-ChangeByte-CopyPart-ShuffleBytes-CopyPart-CopyPart-CrossOver-CrossOver-CrossOver-ShuffleBytes-ChangeByte-ChangeBinInt-ChangeBit-ChangeBit-ChangeBit-ChangeByte-EraseBytes-ChangeByte-ChangeBit-ChangeByte-ChangeByte-CopyPart-PersAutoDict-ChangeBinInt-PersAutoDict-PersAutoDict-PersAutoDict-CopyPart-CopyPart-CrossOver-ChangeByte-ChangeBinInt-ShuffleBytes-ChangeBit-CopyPart-EraseBytes-CopyPart-CopyPart-CrossOver-ChangeByte-EraseBytes-ShuffleBytes-ChangeByte-CopyPart-EraseBytes-CopyPart-CrossOver-ChangeBinInt-ChangeBinInt-InsertByte-ChangeBinInt-ChangeBit-ChangeByte-CopyPart-ChangeByte-EraseBytes-ChangeByte-ChangeBit-ChangeByte-ShuffleBytes-CopyPart-ChangeBinInt-EraseBytes-CrossOver-ChangeBit-ChangeBit-CrossOver-EraseBytes-ChangeBinInt-CopyPart-CopyPart-ChangeBinInt-ChangeBit-EraseBytes-InsertRepeatedBytes-EraseBytes-ChangeBit-CrossOver-CrossOver-EraseBytes-EraseBytes-ChangeByte-CopyPart-CopyPart-ShuffleBytes-ChangeByte-ChangeBit-ChangeByte-EraseBytes-ChangeBit-ChangeByte-ChangeByte-CrossOver-CopyPart-EraseBytes-ChangeByte-EraseBytes-ChangeByte-ShuffleBytes-ShuffleBytes-ChangeByte-CopyPart-ChangeByte-ChangeByte-ChangeBit-CopyPart-ChangeBit-ChangeBinInt-CopyPart-ShuffleBytes-ChangeBit-ChangeBinInt-ChangeBit-EraseBytes-CMP-CrossOver-CopyPart-ChangeBinInt-CrossOver-CrossOver-CopyPart-CrossOver-CrossOver-InsertByte-InsertByte-CopyPart-Custom- DE: "warn"-"\x00\x00\x00\x80"-"\xfe\xff\xff\xfb"-"\xff\xff"-"\x10\x00\x00\x00"-"\xfe\xff\xff\xff"-"\xff\xff\xff\xf6"-"U\x01\x00\x00\x00\x00\x00\x00"-"\xd9\xff\xff\xff"-"\xfe\xff\xff\xea"-"\xf0\xff\xff\xff"-"\xfc\xff\xff\xff"-"warn"-"\xff\xff\xff\xff"-"\xfe\xff\xff\xfb"-"\x00\x00\x00\x80"-"\xfe\xff\xff\xf1"-"\xfe\xff\xff\xea"-"\x00\x00\x00\x00\x00\x00\x012"-"\xe2\x00"-"\xfb\xff\xff\xff"-"\x00\x00\x00\x00"-"\xe9\xff\xff\xff"-"\xff\xff"-"\x00\x00\x00\x80"-"\x01\x00\x04\xc9"-"\xf0\xff\xff\xff"-"\xf9\xff\xff\xff"-"\xff\xff\xff\xff\xff\xff\xff\x12"-"\xe2\x00"-"\xfe\xff\xff\xff"-"\xfe\xff\xff\xea"-"\xff\xff\xff\xff"-"\xf4\xff\xff\xff"-"\xe9\xff\xff\xff"-"\xf1\xff\xff\xff"-
    #48    NEW    cov: 4502 ft: 9151 corp: 27/750Kb lim: 64000 exec/s: 2 rss: 458Mb L: 50772/50772 MS: 259 ChangeByte-ShuffleBytes-ChangeBinInt-ChangeByte-ChangeByte-ChangeByte-ChangeByte-ChangeBit-CopyPart-CrossOver-CopyPart-ChangeByte-CrossOver-CopyPart-ChangeBit-ChangeByte-EraseBytes-ChangeByte-CopyPart-CopyPart-CopyPart-ChangeBit-EraseBytes-ChangeBinInt-CrossOver-CopyPart-CrossOver-CopyPart-ChangeBit-ChangeByte-ChangeBit-InsertByte-CrossOver-InsertRepeatedBytes-InsertRepeatedBytes-InsertRepeatedBytes-ChangeBinInt-EraseBytes-InsertRepeatedBytes-InsertByte-ChangeBit-ShuffleBytes-ChangeBit-ChangeBit-CopyPart-ChangeBit-ChangeByte-CrossOver-ChangeBinInt-ChangeByte-CrossOver-CMP-ChangeByte-CrossOver-ChangeByte-ShuffleBytes-ShuffleBytes-ChangeByte-ChangeBinInt-CopyPart-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-InsertByte-ChangeBit-CopyPart-ChangeBinInt-ChangeByte-CrossOver-ChangeBit-EraseBytes-CopyPart-ChangeBinInt-ChangeBit-ChangeBit-ChangeByte-CopyPart-ChangeBinInt-CrossOver-PersAutoDict-ChangeByte-ChangeBit-ChangeByte-ChangeBinInt-ChangeBinInt-EraseBytes-CopyPart-CopyPart-ChangeByte-ChangeByte-EraseBytes-PersAutoDict-CopyPart-ChangeByte-ChangeByte-EraseBytes-CrossOver-CopyPart-CopyPart-CopyPart-ChangeByte-ChangeBit-CMP-CopyPart-ChangeBinInt-ChangeBinInt-CrossOver-ChangeBit-ChangeBit-EraseBytes-ChangeByte-ShuffleBytes-ChangeBit-ChangeBinInt-CMP-InsertRepeatedBytes-CopyPart-Custom-ChangeByte-CrossOver-EraseBytes-ChangeBit-CopyPart-CrossOver-CMP-ShuffleBytes-EraseBytes-CrossOver-PersAutoDict-ChangeByte-CrossOver-CopyPart-CrossOver-CrossOver-ShuffleBytes-ChangeBinInt-CrossOver-ChangeBinInt-ShuffleBytes-PersAutoDict-ChangeByte-EraseBytes-ChangeBit-CrossOver-EraseBytes-CrossOver-ChangeBit-ChangeBinInt-EraseBytes-InsertByte-InsertRepeatedBytes-InsertByte-InsertByte-ChangeByte-ChangeBinInt-ChangeBit-CrossOver-ChangeByte-CrossOver-EraseBytes-ChangeByte-ShuffleBytes-ChangeBit-ChangeBit-ShuffleBytes-CopyPart-ChangeByte-PersAutoDict-ChangeBit-ChangeByte-InsertRepeatedBytes-CMP-CrossOver-ChangeByte-EraseBytes-ShuffleBytes-CrossOver-ShuffleBytes-ChangeBinInt-ChangeBinInt-CopyPart-PersAutoDict-ShuffleBytes-ChangeBit-CopyPart-ShuffleBytes-CopyPart-EraseBytes-ChangeByte-ChangeBit-ChangeBit-ChangeBinInt-ChangeByte-CopyPart-EraseBytes-ChangeBinInt-EraseBytes-EraseBytes-PersAutoDict-CMP-PersAutoDict-CrossOver-CrossOver-ChangeBit-CrossOver-PersAutoDict-CrossOver-CopyPart-ChangeByte-EraseBytes-ChangeByte-ShuffleBytes-ChangeByte-ChangeByte-CrossOver-ChangeBit-EraseBytes-ChangeByte-EraseBytes-ChangeBinInt-CrossOver-CrossOver-EraseBytes-ChangeBinInt-CrossOver-ChangeBit-ShuffleBytes-ChangeBit-ChangeByte-EraseBytes-ChangeBit-CrossOver-CrossOver-CrossOver-ChangeByte-ChangeBit-ShuffleBytes-ChangeBit-ChangeBit-EraseBytes-CrossOver-CrossOver-CopyPart-ShuffleBytes-ChangeByte-ChangeByte-CopyPart-CrossOver-CopyPart-CrossOver-CrossOver-EraseBytes-EraseBytes-ShuffleBytes-InsertRepeatedBytes-ChangeBit-CopyPart-Custom- DE: "\xfe\xff\xff\xfc"-"\x00\x00\x00\x00"-"F\x00"-"\xf3\xff\xff\xff"-"St9exception"-"_\x00\x00\x00"-"\xf6\xff\xff\xff"-"\xfe\xff\xff\xff"-"\x00\x00\x00\x00"-"p\x02\x00\x00\x00\x00\x00\x00"-"\xfe\xff\xff\xfb"-"\xff\xff"-"\xff\xff\xff\xff"-"\x01\x00\x00\x07"-"\xfe\xff\xff\xfe"-

These are prohibitively large and of limited value in the default case (when
someone is running the fuzzer, not debugging it), in my opinion.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D86658
2020-09-01 11:14:36 -07:00
Dokyung Song c10e63677f Recommit "[libFuzzer] Fix arguments of InsertPartOf/CopyPartOf calls in CrossOver mutator."
The CrossOver mutator is meant to cross over two given buffers (referred to as
the first/second buffer henceforth). Previously InsertPartOf/CopyPartOf calls
used in the CrossOver mutator incorrectly inserted/copied part of the second
buffer into a "scratch buffer" (MutateInPlaceHere of the size
CurrentMaxMutationLen), rather than the first buffer. This is not intended
behavior, because the scratch buffer does not always (i) contain the content of
the first buffer, and (ii) have the same size as the first buffer;
CurrentMaxMutationLen is typically a lot larger than the size of the first
buffer. This patch fixes the issue by using the first buffer instead of the
scratch buffer in InsertPartOf/CopyPartOf calls.

A FuzzBench experiment was run to make sure that this change does not
inadvertently degrade the performance. The performance is largely the same; more
details can be found at:
https://storage.googleapis.com/fuzzer-test-suite-public/fixcrossover-report/index.html

This patch also adds two new tests, namely "cross_over_insert" and
"cross_over_copy", which specifically target InsertPartOf and CopyPartOf,
respectively.

- cross_over_insert.test checks if the fuzzer can use InsertPartOf to trigger
  the crash.

- cross_over_copy.test checks if the fuzzer can use CopyPartOf to trigger the
  crash.

These newly added tests were designed to pass with the current patch, but not
without the it (with 790878f291 these tests do not
pass). To achieve this, -max_len was intentionally given a high value. Without
this patch, InsertPartOf/CopyPartOf will generate larger inputs, possibly with
unpredictable data in it, thereby failing to trigger the crash.

The test pass condition for these new tests is narrowed down by (i) limiting
mutation depth to 1 (i.e., a single CrossOver mutation should be able to trigger
the crash) and (ii) checking whether the mutation sequence of "CrossOver-" leads
to the crash.

Also note that these newly added tests and an existing test (cross_over.test)
all use "-reduce_inputs=0" flags to prevent reducing inputs; it's easier to
force the fuzzer to keep original input string this way than tweaking
cov-instrumented basic blocks in the source code of the fuzzer executable.

Differential Revision: https://reviews.llvm.org/D85554
2020-08-27 21:48:45 +00:00
Matt Morehouse 2392ff093a [libFuzzer] Error and exit if user supplied fuzzer writeable directories don't exist
Currently, libFuzzer will exit with an error message if a non-existent
corpus directory is provided. However, if a user provides a non-existent
directory for the `artifact_prefix`, `exact_artifact_path`, or
`features_dir`, libFuzzer will continue execution but silently fail to
write artifacts/features.

To improve the user experience, this PR adds validation for the existence of
all user supplied directories before executing the main fuzzing loop. If they
don't exist, libFuzzer will exit with an error message.

Patch By: dgg5503

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D84808
2020-08-26 09:27:07 -07:00
Azharuddin Mohammed 8831e34771 Revert "[libFuzzer] Fix arguments of InsertPartOf/CopyPartOf calls in CrossOver mutator."
This reverts commit bb54bcf849.

It is causing the value-profile-load.test test to fail on macOS.
2020-08-21 09:58:50 -07:00
Azharuddin Mohammed 7ed3286a51 [LibFuzzer] [tests] [Darwin] Use the pthread library from the SDK 2020-08-21 09:22:13 -07:00
Dokyung Song bb54bcf849 [libFuzzer] Fix arguments of InsertPartOf/CopyPartOf calls in CrossOver mutator.
The CrossOver mutator is meant to cross over two given buffers (referred to as
the first/second buffer henceforth). Previously InsertPartOf/CopyPartOf calls
used in the CrossOver mutator incorrectly inserted/copied part of the second
buffer into a "scratch buffer" (MutateInPlaceHere of the size
CurrentMaxMutationLen), rather than the first buffer. This is not intended
behavior, because the scratch buffer does not always (i) contain the content of
the first buffer, and (ii) have the same size as the first buffer;
CurrentMaxMutationLen is typically a lot larger than the size of the first
buffer. This patch fixes the issue by using the first buffer instead of the
scratch buffer in InsertPartOf/CopyPartOf calls.

A FuzzBench experiment was run to make sure that this change does not
inadvertently degrade the performance. The performance is largely the same; more
details can be found at:
https://storage.googleapis.com/fuzzer-test-suite-public/fixcrossover-report/index.html

This patch also adds two new tests, namely "cross_over_insert" and
"cross_over_copy", which specifically target InsertPartOf and CopyPartOf,
respectively.

- cross_over_insert.test checks if the fuzzer can use InsertPartOf to trigger
  the crash.

- cross_over_copy.test checks if the fuzzer can use CopyPartOf to trigger the
  crash.

These newly added tests were designed to pass with the current patch, but not
without the it (with 790878f291 these tests do not
pass). To achieve this, -max_len was intentionally given a high value. Without
this patch, InsertPartOf/CopyPartOf will generate larger inputs, possibly with
unpredictable data in it, thereby failing to trigger the crash.

The test pass condition for these new tests is narrowed down by (i) limiting
mutation depth to 1 (i.e., a single CrossOver mutation should be able to trigger
the crash) and (ii) checking whether the mutation sequence of "CrossOver-" leads
to the crash.

Also note that these newly added tests and an existing test (cross_over.test)
all use "-reduce_inputs=0" flags to prevent reducing inputs; it's easier to
force the fuzzer to keep original input string this way than tweaking
cov-instrumented basic blocks in the source code of the fuzzer executable.

Differential Revision: https://reviews.llvm.org/D85554
2020-08-18 16:09:18 +00:00
Ilya Leoshkevich 9df7ee34e1 [libFuzzer] Fix minimizing timeouts
When one tries to minimize timeouts using -minimize_crash=1,
minimization immediately fails. The following sequence of events is
responsible for this:

[parent] SIGALRM occurs
[parent] read() returns -EINTR (or -ERESTARTSYS according to strace)
[parent] fgets() returns NULL
[parent] ExecuteCommand() closes child's stdout and returns
[child ] SIGALRM occurs
[child ] AlarmCallback() attempts to write "ALARM: ..." to stdout
[child ] Dies with SIGPIPE without calling DumpCurrentUnit()
[parent] Does not see -exact_artifact_path and exits

When minimizing, the timer in parent is not necessary, so fix by not
setting it in this case.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D85359
2020-08-11 22:16:12 +02:00
Matt Morehouse b0c50ef759 Revert "Add libFuzzer shared object build output"
This reverts commit 98d91aecb2 since it
breaks on platforms without libstdc++.
2020-08-05 12:11:24 -07:00
Matt Morehouse 2918727588 [libFuzzer] Do not link pthreads on Android.
Android has pthreads included in bionic and doesn't recognize -lpthread.
2020-08-05 11:17:10 -07:00
Matt Morehouse 98d91aecb2 Add libFuzzer shared object build output
This change adds a CMake rule to produce shared object versions of
libFuzzer (no-main). Like the static library versions, these shared
libraries have a copy of libc++ statically linked in. For i386 we don't
link with libc++ since i386 does not support mixing position-
independent and non-position-independent code in the same library.

Patch By: IanPudney

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D84947
2020-08-05 09:03:22 -07:00
Ilya Leoshkevich a4e537d9c4 [libFuzzer] Fix endianness issue in ForEachNonZeroByte()
The usage pattern of Bundle variable assumes the machine is little
endian, which is not the case on SystemZ. Fix by converting Bundle to
little-endian when necessary.
2020-08-04 21:53:27 +02:00
Matt Morehouse e2d0b44a7c [DFSan] Add efficient fast16labels instrumentation mode.
Adds the -fast-16-labels flag, which enables efficient instrumentation
for DFSan when the user needs <=16 labels.  The instrumentation
eliminates most branches and most calls to __dfsan_union or
__dfsan_union_load.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D84371
2020-07-29 18:58:47 +00:00
Matt Morehouse 34ddf0b2b0 Replace fuzzer::FuzzerDriver's INTERFACE marking with new LLVMRunFuzzerDriver.
This adds a new extern "C" function that serves the same purpose. This removes the need for external users to depend on internal headers in order to use this feature. It also standardizes the interface in a way that other fuzzing engines will be able to match.

Patch By: IanPudney

Reviewed By: kcc

Differential Revision: https://reviews.llvm.org/D84561
2020-07-27 18:38:04 +00:00
Fangrui Song f7ffb122d0 [libFuzzer] Instrument bcmp
If we define memcmp in an archive, bcmp should be defined as well (many libc
define bcmp/memcmp in one object file).  Otherwise if the application calls bcmp
or strcmp which gets optimized to bcmp (SimplifyLibCalls), the undefined
reference may pull in an optimized bcmp/strcmp implementation (libc replacement)
later on the linker command line.  If both libFuzzer's memcmp and the optimized
memcmp are strong => there will be a multiple definition error.
2020-07-24 00:24:46 -07:00
Mitch Phillips 540b92147d Revert "[libFuzzer] Expose fuzzer::FuzzerDriver()"
This reverts commit 22a376e73b.
2020-07-23 17:07:55 -07:00
Dokyung Song 45482367ea [libFuzzer] Add a missing include_directories.
Summary: FuzzerInterceptors.cpp includes <sanitizer/common_interface_defs.h>, and this patch adds a missing include_directories to make sure the included file is found.

Reviewers: morehouse, hctim, dmajor

Subscribers: mgorny, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D84474
2020-07-23 23:52:00 +00:00
Mitch Phillips 22a376e73b [libFuzzer] Expose fuzzer::FuzzerDriver()
Summary:
Allows other-language libFuzzer derivatives to invoke the driver.

Patch By: Ian Eldred Pudney <ipudney@google.com>

Reviewers: morehouse, kcc

Reviewed By: morehouse

Subscribers: #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D84425
2020-07-23 12:08:14 -07:00
Dokyung Song 831ae45e3d Recommit "[libFuzzer] Link libFuzzer's own interceptors when other compiler runtimes are not linked."
Summary: libFuzzer intercepts certain library functions such as memcmp/strcmp by defining weak hooks. Weak hooks, however, are called only when other runtimes such as ASan is linked. This patch defines libFuzzer's own interceptors, which is linked into the libFuzzer executable when other runtimes are not linked, i.e., when -fsanitize=fuzzer is given, but not others.

The patch once landed but was reverted in 8ef9e2bf35 due to an assertion failure caused by calling an intercepted function, strncmp, while initializing the interceptors in fuzzerInit(). This issue is now fixed by calling libFuzzer's own implementation of library functions (i.e., internal_*) when the fuzzer has not been initialized yet, instead of recursively calling fuzzerInit() again.

Reviewers: kcc, morehouse, hctim

Subscribers: #sanitizers, krytarowski, mgorny, cfe-commits

Tags: #clang, #sanitizers

Differential Revision: https://reviews.llvm.org/D83494
2020-07-23 15:59:07 +00:00
Vitaly Buka c12f111846 Corrected __libfuzzer_is_present symbol inclusion for MSVC x86 32-bit
The incorrect symbol will cause linking failures for 32-bit targets:

clang_rt.fuzzer-i386.lib(FuzzerDriver.obj) : error LNK2001: unresolved external symbol __libfuzzer_is_present

Verified no longer fails to link with this change for 32-bit and still succeeds for 64-bit MSVC.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D83594
2020-07-17 18:29:47 -07:00
Richard Smith 8ef9e2bf35 Revert "[libFuzzer] Link libFuzzer's own interceptors when other compiler runtimes are not linked."
This causes binaries linked with this runtime to crash on startup if
dlsym uses any of the intercepted functions. (For example, that happens
when using tcmalloc as the allocator: dlsym attempts to allocate memory
with malloc, and tcmalloc uses strncmp within its implementation.)

Also revert dependent commit "[libFuzzer] Disable implicit builtin knowledge about memcmp-like functions when -fsanitize=fuzzer-no-link is given."

This reverts commit f78d9fceea and 12d1124c49.
2020-07-16 18:06:37 -07:00
Dokyung Song f78d9fceea [libFuzzer] Link libFuzzer's own interceptors when other compiler runtimes are not linked.
Summary: libFuzzer intercepts certain library functions such as memcmp/strcmp by defining weak hooks. Weak hooks, however, are called only when other runtimes such as ASan is linked. This patch defines libFuzzer's own interceptors, which is linked into the libFuzzer executable when other runtimes are not linked, i.e., when -fsanitize=fuzzer is given, but not others.

Reviewers: kcc, morehouse, hctim

Reviewed By: morehouse, hctim

Subscribers: krytarowski, mgorny, cfe-commits, #sanitizers

Tags: #clang, #sanitizers

Differential Revision: https://reviews.llvm.org/D83494
2020-07-16 20:26:35 +00:00
Dokyung Song 750369e2e8 [libFuzzer] Fix compilation error by including missing platform macro definitions.
Summary: This patch fixes sanitizer-windows build errors.

Reviewers: morehouse, hctim

Reviewed By: morehouse, hctim

Subscribers: #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D83823
2020-07-14 22:26:50 +00:00
Dokyung Song 226866e115 [libFuzzer] Separate platform related macros out from FuzzerDefs.h into FuzzerPlatform.h, and adjust includes in other files.
Summary: This patch separates platform related macros in lib/fuzzer/FuzzerDefs.h into lib/fuzzer/FuzzerPlatform.h, and use FuzzerPlatform.h where necessary. This separation helps when compiling libFuzzer's interceptor module (under review); an unnecessary include of standard headers (such as string.h) may produce conflicts/ambiguation with the interceptor's declarations/definitions of library functions, which complicates interceptor implementation.

Reviewers: morehouse, hctim

Reviewed By: morehouse

Subscribers: krytarowski, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D83805
2020-07-14 21:31:56 +00:00
Adrian Herrera 4034d0ce20 [libFuzzer] Fixed description of fuzzer merge control file.
Summary:
The description of the fuzzer merge control file appears to be incorrect/out of date.
No "DONE" line appears in the control file. Rather, FT and COV are the markers that appear
following the STARTED line.

Reviewers: metzman, kcc

Reviewed By: kcc

Subscribers: #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D80788
2020-05-29 16:00:26 -07:00
Kostya Serebryany 2e82492540 [fuzzer][afl] Fix build with GCC
Summary:
Fixes this build error with GCC 9.3.0:

```
../lib/fuzzer/afl/afl_driver.cpp:114:30: error: expected unqualified-id before string constant
  114 | __attribute__((weak)) extern "C" void __sanitizer_set_report_fd(void *);
      |                              ^~~
```

Reviewers: metzman, kcc

Reviewed By: kcc

Subscribers: #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D80479
2020-05-26 11:35:50 -07:00
Matt Morehouse 353e5aa42d [libFuzzer] Fix leak in unit test. 2020-05-21 09:02:22 -07:00
Matt Morehouse e2e38fca64 Entropic: Boosting LibFuzzer Performance
Summary:
This is collaboration between Marcel Boehme @ Monash, Australia and Valentin Manès plus Sang Kil Cha @ KAIST, South Korea.

We have made a few modifications to boost LibFuzzer performance by changing how weights are assigned to the seeds in the corpus. Essentially, seeds that reveal more "information" about globally rare features are assigned a higher weight. Our results on the Fuzzer Test Suite seem quite promising. In terms of bug finding, our Entropic patch usually finds the same errors much faster and in more runs. In terms of coverage, our version Entropic achieves the same coverage in less than half the time for the majority of subjects. For the lack of space, we shared more detailed performance results directly with @kcc. We'll publish the preprint with all the technical details as soon as it is accepted. Happy to share if you drop us an email.

There should be plenty of opportunities to optimise further. For instance, while Entropic achieves the same coverage in less than half the time, Entropic has a much lower #execs per second. We ran the perf-tool and found a few performance bottlenecks.

Thanks for open-sourcing LibFuzzer (and the entire LLVM Compiler Infrastructure)! This has been such a tremendous help to my research.

Patch By: Marcel Boehme

Reviewers: kcc, metzman, morehouse, Dor1s, vitalybuka

Reviewed By: kcc

Subscribers: dgg5503, Valentin, llvm-commits, kcc

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73776
2020-05-19 10:28:57 -07:00
Marek Kurdej 8b3d3921b0 [libFuzzer] Fix typo in seed_inputs flag description. NFC. 2020-04-09 13:54:07 +02:00
Max Moroz 2136d17d8d [compiler-rt] Add ConsumeRandomLengthString() version without arguments.
Reviewers: hctim, metzman

Subscribers: dberris, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D76448
2020-03-23 16:32:37 -07:00
serge-sans-paille 292ab49d43 Fix UB in compiler-rt base64 implementation
As a follow-up to 1454c27b60
2020-03-03 13:28:32 +01:00
serge-sans-paille 1454c27b60 Syndicate, test and fix base64 implementation
llvm/Support/Base64, fix its implementation and provide a decent test suite.

Previous implementation code was using + operator instead of | to combine

results, which is a problem when shifting signed values. (0xFF << 16) is
implicitly converted to a (signed) int, and thus results in 0xffff0000,
h is
negative. Combining negative numbers with a + in that context is not what we
want to do.

This is a recommit of 5a1958f267 with UB removved.

This fixes https://github.com/llvm/llvm-project/issues/149.

Differential Revision: https://reviews.llvm.org/D75057
2020-03-03 12:17:53 +01:00
Mitch Phillips 49684f9db5 Revert "Syndicate, test and fix base64 implementation"
This reverts commit 5a1958f267.

This change broke the UBSan build bots. See
https://reviews.llvm.org/D75057 for more information.
2020-03-02 09:33:22 -08:00
serge-sans-paille 5a1958f267 Syndicate, test and fix base64 implementation
Move Base64 implementation from clangd/SemanticHighlighting to
llvm/Support/Base64, fix its implementation and provide a decent test suite.

Previous implementation code was using + operator instead of | to combine some
results, which is a problem when shifting signed values. (0xFF << 16) is
implicitly converted to a (signed) int, and thus results in 0xffff0000, which is
negative. Combining negative numbers with a + in that context is not what we
want to do.

This fixes https://github.com/llvm/llvm-project/issues/149.

Differential Revision: https://reviews.llvm.org/D75057
2020-03-02 10:02:25 +01:00
Max Moroz 076475713c [libFuzzer] Fix denominator in the "inputs have DFT" log line.
Summary:
The number of "inputs have the Data Flow Trace" cannot be greater than
the number of inputs touching the focus function. The existing message is rather
confusing as the same log would mention a greater total number of traces a few
lines above.

Reviewers: kcc, metzman

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D74779
2020-02-19 11:05:14 -08:00
Yuanfang Chen 4caeb62e51 [Fuzzer] Rename ExecuteCommandWithPopen to ExecuteCommandNon-Fushsia target will keep using popen/pclose implementation. OnFuchsia, Two-args version of `ExecuteCommand` is a simple wrapper of theone-arg version. (Hopefully) Fix D73329 build on Fuchsia. 2020-02-12 16:03:55 -08:00
Max Moroz 20a604d3f5 [compiler-rt] FuzzedDataProvider: add ConsumeData and method.
Reviewers: metzman

Subscribers: dberris, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D74359
2020-02-11 13:46:24 -08:00
Yuanfang Chen 4f3c3bbbf8 Reland "[NFC][libFuzzer] Prefix TempPath with string showing the work it is doing."
With fix (somehow one hunk is missed).
2020-02-10 18:23:39 -08:00
Yuanfang Chen b1c7623982 Revert "[NFC][libFuzzer] Prefix TempPath with string showing the work it is doing."
This reverts commit 8a29cb4421.

fuzzer-linux bot has failure because of this.
2020-02-10 18:06:17 -08:00
Yuanfang Chen 8a29cb4421 [NFC][libFuzzer] Prefix TempPath with string showing the work it is doing. 2020-02-10 16:45:10 -08:00
Yuanfang Chen 85515c7fd5 [libFuzzer] communicate through pipe to subprocess for MinimizeCrashInput
For CleanseCrashInput, discards stdout output anyway since it is not used.

These changes are to defend against aggressive PID recycle on windows to reduce the chance of contention on files.

Using pipe instead of file also workaround the problem that when the
process is spawned by llvm-lit, the aborted process keeps a handle to the
output file such that the output file can not be removed. This will
cause random test failures.

https://devblogs.microsoft.com/oldnewthing/20110107-00/?p=11803

Reviewers: kcc, vitalybuka

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D73329
2020-02-10 16:45:10 -08:00
Max Moroz ad7b908b4e [libFuzzer] Make dataflow and focus functions more user friendly.
Summary:
- Fail loudly if SetFocusFunction failed when it should not. For more info see
  - https://github.com/google/oss-fuzz/issues/3311
  - https://github.com/google/sanitizers/issues/1190
- Fail loudly if CollectDataFlow is called without seed corpus.

Reviewers: kcc, metzman

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73813
2020-02-03 08:36:03 -08:00
Dan Liew 9d9b470e69 [CMake] Refactor iOS simulator/device test configuration generation code for LibFuzzer.
Summary:
In order to do this `FUZZER_SUPPORTED_OS` had to be pulled out of
`lib/fuzzer/CMakeLists.txt` and into the main config so we can use it
from the `test/fuzzer/CMakeList.txt`. `FUZZER_SUPPORTED_OS` currently
has the same value of `SANITIZER_COMMON_SUPPORTED_OS` which preserves
the existing behaviour but this allows us in the future to adjust the
supported platforms independent of `SANITIZER_COMMON_SUPPORTED_OS`. This
mirrors the other sanitizers.

For non-Apple platforms `FUZZER_SUPPORTED_OS` is not defined and
surprisingly this was the behaviour before this patch because
`SANITIZER_COMMON_SUPPORTED_OS` was actually empty. This appears to
not matter right now because the functions that take an `OS` as an
argument seem to ignore it on non-Apple platforms.

While this change tries to be NFC it is technically not because we
now generate an iossim config whereas previously we didn't. This seems
like the right thing to do because the build system was configured to
compile LibFuzzer for iossim but previously we weren't generating a lit
test config for it. The device/simulator testing configs don't run by
default anyway so this shouldn't break testing.

This change relies on the get_capitalized_apple_platform() function
added in a previous commit.

rdar://problem/58798733

Reviewers: kubamracek, yln

Subscribers: mgorny, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73243
2020-01-23 12:44:00 -08:00
Max Moroz 15f1d5d144 [libFuzzer] Add INFO output when LLVMFuzzerCustomMutator is found.
Summary:
there is an ongoing work on interchangeable custom mutators
(https://github.com/google/clusterfuzz/pull/1333/files#r367706283)
and having some sort of signalling from libFuzzer that it has loaded
a custom mutator would be helpful.

The initial idea was to make the mutator to print something, but given
the anticipated variety of different mutators, it does not seem possible
to make all of them print the same message to signal their execution.

Reviewers: kcc, metzman

Reviewed By: metzman

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73136
2020-01-22 12:56:16 -08:00
Marco Vanotti 44aaca3de4 [libFuzzer] Allow discarding output in ExecuteCommand in Fuchsia.
Summary:
This commit modifies the way `ExecuteCommand` works in fuchsia by adding
special logic to handle `/dev/null`.

The FuzzerCommand interface does not have a way to "discard" the output,
so other parts of the code just set the output file to `getDevNull()`.
The problem is that fuchsia does not have a named file that is
equivalent to `/dev/null`, so opening that file just fails.

This commit detects whether the specified output file is `getDevNull`,
and if that's the case, it will not copy the file descriptor for stdout
in the spawned process.

NOTE that modifying `FuzzerCommand` to add a "discardOutput" function
involves a significant refactor of all the other platforms, as they all
rely on the `toString()` method of `FuzzerCommand`.

This allows libfuzzer in fuchsia to run with `fork=1`, as the merge
process (`FuzzerMerge.cpp`) invoked `ExecuteCommand` with `/dev/null` as the
output.

Reviewers: aarongreen, phosek

Reviewed By: aarongreen

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D72894
2020-01-17 12:15:46 -08:00
Kamil Rytarowski 7e8541f3df [compiler-rt] [fuzzer] Include stdarg.h for va_list
Fixes build on NetBSD after 139e216e66.
2019-12-19 01:11:39 +01:00
Max Moroz 926fa4088c [compiler-rt] libFuzzer: update -merge_control_file= help message.
Summary:
The motivation for this change is to have a distinguisher in libFuzzer
that would let the runner know whether multistep merge is supported or not by
a particular fuzz target binary. Otherwise, multistep merge fails to execute
with older version of libFuzzer, and there is no way to verify that easily.

Reviewers: kcc

Subscribers: dberris, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D71423
2019-12-12 11:09:40 -08:00
Jonathan Metzman 23bee0b0cf [fuzzer] Add basic support for emscripten.
Summary:
Add basic support for emscripten.

This enables libFuzzer to build (using build.sh) for emscripten and fuzz
a target compiled with
-fsanitize-coverage=inline-8bit-counters.

Basic fuzzing and bug finding work with this commit.
RSS limit and timeouts will not work because they depend on system
functions that are not implemented/widely supported in emscripten.

Reviewers: kcc, vitalybuka, hctim

Reviewed By: hctim

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D71285
2019-12-12 08:56:47 -08:00
Marco Vanotti e5b603a4c3 [libFuzzer] don't use /dev/null for DiscardOuput in Fuchsia.
Summary:

This commit moves the `DiscardOutput` function in FuzzerIO to
FuzzerUtil, so fuchsia can have its own specialized version.

In fuchsia, accessing `/dev/null` is not supported, and there's nothing
similar to a file that discards everything that is written to it. The
way of doing something similar in fuchsia is by using `fdio_null_create`
and binding that to a file descriptor with `fdio_bind_to_fd`.

This change should fix one of the issues with the `-close_fd_mask` flag
in libfuzzer, in which closing stdout was not working due to
`fopen("/dev/null", "w")` returning `NULL`.

Reviewers: kcc, aarongreen

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D69593
2019-11-21 16:56:05 -08:00
Marco Vanotti 46c7fc22cf [libFuzzer] Fix unwinding for Fuchsia
Summary:
This commit fixes part of the issues with stack unwinding in fuchsia for
arm64 and x86_64. It consists of multiple fixes:

(1) The cfa_offset calculation was wrong, instead of pointing to the
previous stack pointer, it was pointing to the current  one. It worked in
most of the cases because the crashing functions already had a
prologue and had their cfa information relative to another register. The
fix consists on adding a constant that can be used to calculate the
crashing function's stack pointer, and base all the cfi information
relative to that offset.

(2) (arm64) Due to errors with the syntax for the dwarf information, most
of the `OP_NUM` macros were not working. The problem was that they were
referred to as `r##NUM` (like `r14`), when it should have been `x##num`
(like `x14`), or even without the x.

(3) (arm64) The link register was being considered a part of the main
registers (`r30`), when in the real struct it has its own field. Given
that the link register is in the same spot in the struct as r[30] would be,
and that C++ doesn't care about anything, the calculation was still correct.

(4) (x86_64) The stack doesn't need to be aligned to 16 bytes when we
jump to the trampoline function, but it needs to be before performing
call instructions. Encoding that logic in cfi information was tricky, so
we decided to make the cfa information relative to `rbp` and align `rsp`.
Note that this could have been done using another register directly,
but it seems cleaner to make a new fake stack frame.

There are some other minor changes like adding a `brk 1` instruction in
arm64 to make sure that we never return to the crash trampoline (similar to
what we do in x86_64).

Sadly this commit does not fix unwinding for all use cases for arm64.
Crashing functions that do not add information related to the return column in
their cfi information will fail to unwind due to a bug in libunwinder.

Reviewers: mcgrathr, jakehehrlich, phosek, kcc, aarongreen

Subscribers: aprantl, kristof.beyls, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D69579
2019-11-21 15:47:07 -08:00
Marco Vanotti 16d9f44fd1 [libFuzzer] Fix fd check in DupAndCloseStderr.
Summary:
This commit fixes the check in the return value from the `DuplicateFile`
function, which returns a new file descriptor. `DuplicateFile` can
return 0 if that file descriptor is available (for example, if stdin has
already been closed).

In particular, this could cause a bug with the `-close_fd_mask` flag in
some platforms: just call the fuzzer with stdin closed and the
`-close_fd_mask=2` flag, and stderr will not be muted.

Example fuzzer:

```

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  fprintf(stderr, "STDERR\n");
  fprintf(stdout, "STDOUT\n");
  return 0;
}
```

Invocation (muting both stderr and stdout):
```
./test -close_fd_mask=3 -runs=1 0<&-
INFO: Seed: 1155116940
INFO: Loaded 1 modules   (1 inline 8-bit counters): 1 [0x48b020, 0x48b021),
INFO: Loaded 1 PC tables (1 PCs): 1 [0x478dc8,0x478dd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
STDERR
INFO: A corpus is not provided, starting from an empty corpus
STDERR
Done 2 runs in 0 second(s)
```

Reviewers: mcgrathr, jakehehrlich, phosek, kcc, aarongreen

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D68775
2019-11-21 15:25:10 -08:00
Evgenii Stepanov 961d48df28 Disable exceptions in libfuzzer's copy of libcxxabi.
External project configuration for libcxxabi now has exceptions on by
default, but this is not needed for libfuzzer.
2019-11-01 10:05:59 -07:00
Louis Dionne 3c9063f5d2 [libc++] Force the ABI namespace to be a reserved identifier
Summary:
When the ABI namespace isn't a reserved identifier, we were issuing a
warning, but this should have been an error since the beginning. This
commit enforces that the ABI namespace is a reserved identifier, and
changes the ABI namespace used by LibFuzzer.

Reviewers: phosek, EricWF

Subscribers: mgorny, christof, jkorous, dexonsmith, #sanitizers, libcxx-commits, llvm-commits

Tags: #sanitizers, #libc, #llvm

Differential Revision: https://reviews.llvm.org/D69408
2019-10-29 10:55:43 -07:00
Matt Morehouse a88591cff4 [libFuzzer] Enable extra counters for Fuchsia. 2019-10-25 16:12:59 -07:00
Jake Ehrlich cde860a1c9 [libFuzzer] Don't prefix absolute paths in fuchsia.
The ExecuteCommand function in fuchsia used to prefix the
getOutputFile for each command run with the artifact_prefix flag if
it was available, because fuchsia components don't have a writable working
directory. However, if a file with a global path is provided, fuchsia
should honor that.

An example of this is using the global /tmp directory to store stuff.
In fuchsia it ended up being translated to data///tmp, whereas we want
to make sure it is using /tmp (which is available to components using the
isolated-temp feature).

To test this I made the change, compiled fuchsia with this toolchain and
ran a fuzzer with the -fork=1 flag (that mode makes use of the /tmp
directory). I also tested that normal fuzzing workflow was not affected
by this.

Author: charco (Marco Vanotti)
Differential Revision: https://reviews.llvm.org/D68774

llvm-svn: 374612
2019-10-11 23:35:13 +00:00
Jake Ehrlich e7bfce7863 [libFuzzer] Fix Alarm callback in fuchsia.
This patch adds an #if macro to skip the InFuzzingThread() comparison
for fuchsia, similar to what it is done for Windows and NetBSD.

In fuchsia, the alarm callback runs in a separate thread[0], making it fail
the comparison InFuzzingThread(), breaking the -timeout flag.

[0]:
https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp#L323

Author: charco (aka Marco  Vanotti)
Differential Revision: https://reviews.llvm.org/D68166

llvm-svn: 374228
2019-10-09 21:01:50 +00:00
Matt Morehouse 1c8e05110c [libFuzzer] Remove lazy counters.
Summary: Lazy counters haven't improved performance for large fuzz targets.

Reviewers: kcc

Reviewed By: kcc

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67476

llvm-svn: 373403
2019-10-01 22:49:06 +00:00
Mitch Phillips d1e222e552 [libFuzzer] Dump trace and provide correct msg for overwritten input.
Summary:
Now crashes with a stacktrace and uses 'overwrites-const-input' as the error
message instead of 'out-of-memory'.

Reviewers: morehouse, Dor1s

Reviewed By: morehouse, Dor1s

Subscribers: #sanitizers, llvm-commits, metzman, Dor1s

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D68067

llvm-svn: 373130
2019-09-27 22:04:36 +00:00
Mitch Phillips da3cf61654 [libFuzzer] [NFC] Fix grammar error with "it's"
llvm-svn: 372937
2019-09-26 00:54:30 +00:00
Jake Ehrlich 4b23c24bc8 [libFuzzer] Always print DSO map on Fuchsia libFuzzer launch
Fuchsia doesn't have /proc/id/maps, so it relies on the kernel logging system
to provide the DSO map to be able to symbolize in the context of ASLR. The DSO
map is logged automatically on Fuchsia when encountering a crash or writing to
the sanitizer log for the first time in a process. There are several cases
where libFuzzer doesn't encounter a crash, e.g. on timeouts, OOMs, and when
configured to print new PCs as they become covered, to name a few. Therefore,
this change always writes to the sanitizer log on startup to ensure the DSO map
is available in the log.

Author: aarongreen
Differential Revision: https://reviews.llvm.org/D66233

llvm-svn: 372056
2019-09-17 00:34:41 +00:00
Max Moroz d0f63f83e7 [libFuzzer] Remove unused version of FuzzedDataProvider.h.
Summary: The actual version lives in compiler-rt/include/fuzzer/.

Reviewers: Dor1s

Reviewed By: Dor1s

Subscribers: delcypher, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D67623

llvm-svn: 371997
2019-09-16 15:00:21 +00:00
Max Moroz f054067f27 [libFuzzer] Make -merge=1 to reuse coverage information from the control file.
Summary:
This change allows to perform corpus merging in two steps. This is useful when
the user wants to address the following two points simultaneously:

1) Get trustworthy incremental stats for the coverage and corpus size changes
    when adding new corpus units.
2) Make sure the shorter units will be preferred when two or more units give the
    same unique signal (equivalent to the `REDUCE` logic).

This solution was brainstormed together with @kcc, hopefully it looks good to
the other people too. The proposed use case scenario:

1) We have a `fuzz_target` binary and `existing_corpus` directory.
2) We do fuzzing and write new units into the `new_corpus` directory.
3) We want to merge the new corpus into the existing corpus and satisfy the
    points mentioned above.
4) We create an empty directory `merged_corpus` and run the first merge step:

    `
    ./fuzz_target -merge=1 -merge_control_file=MCF ./merged_corpus ./existing_corpus
    `

    this provides the initial stats for `existing_corpus`, e.g. from the output:

    `
    MERGE-OUTER: 3 new files with 11 new features added; 11 new coverage edges
    `

5) We recreate `merged_corpus` directory and run the second merge step:

    `
    ./fuzz_target -merge=1 -merge_control_file=MCF ./merged_corpus ./existing_corpus ./new_corpus
    `

    this provides the final stats for the merged corpus, e.g. from the output:

    `
    MERGE-OUTER: 6 new files with 14 new features added; 14 new coverage edges
    `

Alternative solutions to this approach are:

A) Store precise coverage information for every unit (not only unique signal).
B) Execute the same two steps without reusing the control file.

Either of these would be suboptimal as it would impose an extra disk or CPU load
respectively, which is bad given the quadratic complexity in the worst case.

Tested on Linux, Mac, Windows.

Reviewers: morehouse, metzman, hctim, kcc

Reviewed By: morehouse

Subscribers: JDevlieghere, delcypher, mgrang, #sanitizers, llvm-commits, kcc

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D66107

llvm-svn: 371620
2019-09-11 14:11:08 +00:00
Matthew G McGovern 2eaeba6f15 LibFuzzer support for 32bit MSVC
This fixes the two build errors when trying to compile LibFuzzer for
32bit with MSVC.

    - authored by Max Shavrick (mxms at microsoft)

llvm-svn: 369704
2019-08-22 20:44:34 +00:00
Sam McCall a451156bb6 reland [gtest] Fix printing of StringRef and SmallString in assert messages.
Renames GTEST_NO_LLVM_RAW_OSTREAM -> GTEST_NO_LLVM_SUPPORT and guards
the new features behind it.

This reverts commit a063bcf3ef5a879adbe9639a3c187d876eee0e66.

llvm-svn: 369527
2019-08-21 13:56:29 +00:00
Max Moroz 74cec618f3 [libFuzzer] Merge: print feature coverage number as well.
Summary:
feature coverage is a useful signal that is available during the merge
process, but was not printed previously.

Output example:

```
$ ./fuzzer -use_value_profile=1 -merge=1 new_corpus/ seed_corpus/
INFO: Seed: 1676551929
INFO: Loaded 1 modules   (2380 inline 8-bit counters): 2380 [0x90d180, 0x90dacc), 
INFO: Loaded 1 PC tables (2380 PCs): 2380 [0x684018,0x68d4d8), 
MERGE-OUTER: 180 files, 78 in the initial corpus
MERGE-OUTER: attempt 1
INFO: Seed: 1676574577
INFO: Loaded 1 modules   (2380 inline 8-bit counters): 2380 [0x90d180, 0x90dacc), 
INFO: Loaded 1 PC tables (2380 PCs): 2380 [0x684018,0x68d4d8), 
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 1048576 bytes
MERGE-INNER: using the control file '/tmp/libFuzzerTemp.111754.txt'
MERGE-INNER: 180 total files; 0 processed earlier; will process 180 files now
#1	pulse  cov: 134 ft: 330 exec/s: 0 rss: 37Mb
#2	pulse  cov: 142 ft: 462 exec/s: 0 rss: 38Mb
#4	pulse  cov: 152 ft: 651 exec/s: 0 rss: 38Mb
#8	pulse  cov: 152 ft: 943 exec/s: 0 rss: 38Mb
#16	pulse  cov: 520 ft: 2783 exec/s: 0 rss: 39Mb
#32	pulse  cov: 552 ft: 3280 exec/s: 0 rss: 41Mb
#64	pulse  cov: 576 ft: 3641 exec/s: 0 rss: 50Mb
#78	LOADED cov: 602 ft: 3936 exec/s: 0 rss: 88Mb
#128	pulse  cov: 611 ft: 3996 exec/s: 0 rss: 93Mb
#180	DONE   cov: 611 ft: 4016 exec/s: 0 rss: 155Mb
MERGE-OUTER: succesfull in 1 attempt(s)
MERGE-OUTER: the control file has 39741 bytes
MERGE-OUTER: consumed 0Mb (37Mb rss) to parse the control file
MERGE-OUTER: 9 new files with 80 new features added; 9 new coverage edges
```

Reviewers: hctim, morehouse

Reviewed By: morehouse

Subscribers: delcypher, #sanitizers, llvm-commits, kcc

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D66030

llvm-svn: 368617
2019-08-12 20:21:27 +00:00
Max Moroz 3653aeeffa [libFuzzer] Merge: print stats after reading the output corpus dir.
Summary:
The purpose is to be able to extract the number of new edges added to
the original (i.e. output) corpus directory after doing the merge. Use case
example: in ClusterFuzz, we do merge after every fuzzing session, to avoid
uploading too many corpus files, and we also record coverage stats at that
point. Having a separate line indicating stats after reading the initial output
corpus directory would make the stats extraction easier for both humans and
parsing scripts.

Context: https://github.com/google/clusterfuzz/issues/802.

Reviewers: morehouse, hctim

Reviewed By: hctim

Subscribers: delcypher, #sanitizers, llvm-commits, kcc

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D66020

llvm-svn: 368461
2019-08-09 18:20:53 +00:00
Max Moroz df3b465c9c [compiler-rt] Add ConsumeProbability and ConsumeFloatingPoint methods to FDP.
Summary:
Also slightly cleaned up the comments and changed the header's extension
back to `.h` as per comments on https://reviews.llvm.org/D65812.

New methods added:

* `ConsumeProbability` returns [0.0, 1.0] by consuming an unsigned integer value
   from the input data and dividing that value by the integer's max value.
* `ConsumeFloatingPointInRange` returns a floating point value in the given
   range. Relies on `ConsumeProbability` method. This method does not have the
   limitation of `std::uniform_real_distribution` that requires the given range
   to be <= the floating point type's max. If the range is too large, this
   implementation will additionally call `ConsumeBool` to decide whether the
   result will be in the first or the second half of the range.
* `ConsumeFloatingPoint` returns a floating point value in the range
  `[std::numeric_limits<T>::lowest(), std::numeric_limits<T>::min()]`.

Tested on Linux, Mac, Windows.


Reviewers: morehouse

Reviewed By: morehouse

Subscribers: kubamracek, mgorny, dberris, delcypher, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D65905

llvm-svn: 368331
2019-08-08 19:49:37 +00:00
Max Moroz 6c619aadc4 [compiler-rt] Rename FuzzedDataProvider.h to .hpp and other minor changes.
Summary:
.hpp makes more sense for this header as it's C++ only, plus it
contains the actual implementation.

Reviewers: Dor1s

Reviewed By: Dor1s

Subscribers: kubamracek, dberris, mgorny, delcypher, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D65812

llvm-svn: 368054
2019-08-06 16:02:39 +00:00
Yi Kong 295d4b7727 Build libfuzzer libcxx-static with PIC
r356153 changed default build option of static libcxx to no PIC. We now
need to explicitly specify CMAKE_POSITION_INDEPENDENT_CODE to get PIC
libcxx.

Differential Revision: https://reviews.llvm.org/D65773

llvm-svn: 367943
2019-08-05 22:55:17 +00:00
Max Moroz f1b0a93e3a [compiler-rt] Move FDP to include/fuzzer/FuzzedDataProvider.h for easier use.
Summary:
FuzzedDataProvider is a helper class for writing fuzz targets that fuzz
multple inputs simultaneously. The header is supposed to be used for fuzzing
engine agnostic fuzz targets (i.e. the same target can be used with libFuzzer,
AFL, honggfuzz, and other engines). The common thing though is that fuzz targets
are typically compiled with clang, as it provides all sanitizers as well as
different coverage instrumentation modes. Therefore, making this FDP class a
part of the compiler-rt installation package would make it easier to develop
and distribute fuzz targets across different projects, build systems, etc.
Some context also available in https://github.com/google/oss-fuzz/pull/2547.

This CL does not delete the header from `lib/fuzzer/utils` directory in order to
provide the downstream users some time for a smooth migration to the new
header location.

Reviewers: kcc, morehouse

Reviewed By: morehouse

Subscribers: lebedev.ri, kubamracek, dberris, mgorny, delcypher, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D65661

llvm-svn: 367917
2019-08-05 19:55:52 +00:00