Thin interface for LLVM/Clang libFuzzer, an in-process, coverage-guided, evolutionary fuzzing engine.
Fuzzing is a type of automated testing which continuously manipulates inputs to a program to find issues such as panics or bugs. These semi-random data mutations can discover new code coverage that existing unit tests may miss, and uncover edge case bugs which would otherwise go unnoticed. Since fuzzing can reach these edge cases, fuzz testing is particularly valuable for finding security exploits and vulnerabilities.
Read the Documentation
Sanitizers are compiler build-in error detectors with relatively small runtime cost. Clang has:
- AddressSanitizer - use-after-free, double-free, ...
- MemorySanitizer - uninitialized reads
- UndefinedBehaviourSanitizer - overflows, divide by zero, ...
- ThreadSanitizer - data races
For more information watch the talk Sanitize your C++ code [4] There are demos at the tests directory.
In 95% of cases all you need is to define the procedure testOneInput
in your file.
proc fuzzMe(data: openarray[byte]): bool =
result = data.len >= 3 and
data[0].char == 'F' and
data[1].char == 'U' and
data[2].char == 'Z' and
data[3].char == 'Z' # :‑<
proc initialize(): cint {.exportc: "LLVMFuzzerInitialize".} =
{.emit: "N_CDECL(void, NimMain)(void); NimMain();".}
proc testOneInput(data: ptr UncheckedArray[byte], len: int): cint {.
exportc: "LLVMFuzzerTestOneInput", raises: [].} =
result = 0
discard fuzzMe(data.toOpenArray(0, len-1))
Compile with:
$ nim c --cc:clang -t:"-fsanitize=fuzzer,address,undefined" -l:"-fsanitize=fuzzer,address,undefined" -d:nosignalhandler --nomain:on -g tfuzz.nim
Use Clang Coverage to visualize and study your code coverage.
- Include the standalone main procedure for fuzz targets.
- Follow the instructions given at the test coverage example.
- When running the executable, pass as parameter a list of test units.
But the lack of an input grammar can also result in inefficient fuzzing for complicated input types, where any traditional mutation (e.g. bit flipping) leads to an invalid input rejected by the target API in the early stage of parsing. With some additional effort, however, libFuzzer can be turned into a grammar-aware (i.e. structure-aware) fuzzing engine for a specific input type.
—Structure-Aware Fuzzing with libFuzzer [5]
Take a look at the snappy compression example and ` <experiments/nfpsum.nim>`_
- Copy the files
libfuzzer/fuzztarget.{nim,nims}
,libfuzzer/standalone.nim
at your testing directory. - Fill in the implementations of the exported procedures.
- Compile and run with an empty corpus directory as an argument.
[1] | Jonathan Metzman Fuzzing 101 |
[2] | Kostya Serebryany Fuzz or lose... |
[3] | Kostya Serebryany Sanitize your C++ code |
[4] | libFuzzer Tutorial |
[5] | Structure-Aware Fuzzing with libFuzzer |
[6] | Efficient Fuzzing Guide |