Remove standalone define and add specific afl/libFuzzer define

This commit is contained in:
kdeme 2019-10-11 14:46:54 +02:00
parent 9ee208876d
commit 757ac1ab86
No known key found for this signature in database
GPG Key ID: 4E8DD21420AF43F5
5 changed files with 34 additions and 21 deletions

View File

@ -329,6 +329,9 @@ proc rlpHash*[T](v: T): Hash256 =
func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
proc notImplemented =
when defined(afl) or defined(libFuzzer):
discard
else:
doAssert false, "Method not implemented"
template hasData*(b: Blob): bool = b.len > 0

View File

@ -7,6 +7,7 @@ proc aflSwitches() =
switch("out", "fuzz-afl")
proc libFuzzerSwitches() =
switch("define", "libFuzzer")
switch("noMain", "")
switch("cc", "clang")
switch("passC", "-fsanitize=fuzzer,address")

View File

@ -44,7 +44,7 @@ type
clangFast = aflClangFast
proc aflCompile*(target: string, c: Compiler) =
let aflOptions = &"-d:standalone -d:noSignalHandler {$c}"
let aflOptions = &"-d:afl -d:noSignalHandler {$c}"
let compileCmd = &"nim c {defaultFlags} {aflOptions} {target.quoteShell()}"
exec compileCmd
@ -66,7 +66,7 @@ proc aflExec*(target: string, inputDir: string, resultsDir: string,
exec fuzzCmd
proc libFuzzerCompile*(target: string) =
let libFuzzerOptions = &"--noMain {libFuzzerClang}"
let libFuzzerOptions = &"-d:libFuzzer --noMain {libFuzzerClang}"
let compileCmd = &"nim c {defaultFlags} {libFuzzerOptions} {target.quoteShell()}"
exec compileCmd

View File

@ -3,7 +3,7 @@ import streams, posix, strutils, chronicles, macros, stew/ranges/ptr_arith
template fuzz(body) =
# For code we want to fuzz, SIGSEGV is needed on unwanted exceptions.
# However, this is only needed when fuzzing with afl.
when defined(standalone):
when defined(afl):
try:
body
except Exception as e:
@ -29,7 +29,7 @@ proc NimMain() {.importc: "NimMain".}
# The default init, gets redefined when init template is used.
template initImpl(): untyped =
when defined(standalone):
when not defined(libFuzzer):
discard
else:
proc fuzzerInit(): cint {.exportc: "LLVMFuzzerInitialize".} =
@ -46,7 +46,7 @@ template init*(body: untyped) =
## For libFuzzer this will only be run once. So only put data which is
## stateless or make sure everything gets properply reset for each new run in
## the test block.
when defined(standalone):
when not defined(libFuzzer):
template initImpl(): untyped = fuzz: `body`
else:
template initImpl() =
@ -64,7 +64,7 @@ template test*(body: untyped): untyped =
## contains the payload provided by the fuzzer.
mixin initImpl
initImpl()
when defined(standalone):
when not defined(libFuzzer):
var payload {.inject.} = readStdin()
fuzz: `body`
@ -76,8 +76,6 @@ template test*(body: untyped): untyped =
`body`
# var aflClangFast {.importc: "__AFL_HAVE_MANUAL_CONTROL", noDecl.}: int
when defined(clangfast):
## Can be used for deferred instrumentation.
## Should be placed on a suitable location in the code where the delayed

View File

@ -92,9 +92,9 @@ nim fuzz.nims libFuzzer testcase.nim
#### Compiling
With gcc:
```sh
nim c -d:standalone -d:release -d:chronicles_log_level=fatal -d:noSignalHandler --cc=gcc --gcc.exe=afl-gcc --gcc.linkerexe=afl-gcc testcase.nim
nim c -d:afl -d:release -d:chronicles_log_level=fatal -d:noSignalHandler --cc=gcc --gcc.exe=afl-gcc --gcc.linkerexe=afl-gcc testcase.nim
```
The `standalone` define is specifically required for the `init` and `test`
The `afl` define is specifically required for the `init` and `test`
templates.
You typically want to fuzz in `-d:release` and probably also want to lower down
@ -108,9 +108,9 @@ nim c build_afl testcase.nim
With clang:
```sh
# afl-clang
nim c -d:standalone -d:noSignalHandler --cc=clang --clang.exe=afl-clang --clang.linkerexe=afl-clang ftestcase.nim
nim c -d:afl -d:noSignalHandler --cc=clang --clang.exe=afl-clang --clang.linkerexe=afl-clang ftestcase.nim
# afl-clang-fast
nim c -d:standalone -d:noSignalHandler --cc=clang --clang.exe=afl-clang-fast --clang.linkerexe=afl-clang-fast testcase.nim
nim c -d:afl -d:noSignalHandler --cc=clang --clang.exe=afl-clang-fast --clang.linkerexe=afl-clang-fast testcase.nim
```
#### Starting the Fuzzer
@ -135,17 +135,26 @@ afl-fuzz -i input -o results -S fuzzer03 -- ./testcase
# add more if needed
```
When compiled with `-d:standalone` the resulting application can also be run
When compiled with `-d:afl` the resulting application can also be run
manually by providing it input data, e.g.:
```sh
cat testfile | ./testcase
./testcase < testfile
```
During debugging you might not want the testcase to generate a segmentation
fault on exceptions. You can do this by rebuilding the test without the `-d:afl`
flag. Changing to `-d:debug` will also help but might also change the
behaviour.
### Manually with libFuzzer
#### Compiling
```sh
nim c -d:release -d:chronicles_log_level=fatal --noMain --cc=clang --passC="-fsanitize=fuzzer" --passL="-fsanitize=fuzzer" testcase.nim
nim c -d:libFuzzer -d:release -d:chronicles_log_level=fatal --noMain --cc=clang --passC="-fsanitize=fuzzer" --passL="-fsanitize=fuzzer" testcase.nim
```
The `libFuzzer` define is specifically required for the `init` and `test`
templates.
You typically want to fuzz in `-d:release` and probably also want to lower down
the logging. But this is not strictly necessary.
@ -180,14 +189,16 @@ The `init` template, when used with **afl**, is only cosmetic. It will be
run before each test block, compared to libFuzzer, where it will be run only
once.
In case of using afl with `alf-clang-fast` you can make use of `aflInit()` and
`aflLoop()` calls.
In case of using afl with `alf-clang-fast` you can make use of `aflInit()` proc
and `aflLoop()` template.
`aflInit()` will allow using what is called deferred instrumentation. Basically,
the forking of the process will only happen after this call, where normally it
is done right before `main()`.
`aflLoop(cint)` will allow for (experimental) persistant mode. This is more
comparable with libFuzzer.
`aflLoop:` will allow for (experimental) persistant mode. It will run the test
in loop (1000 iterations) with different payloads. This is more comparable with
libFuzzer.
These calls are enabled with `-d:clangfast`.
These calls are enabled with `-d:clangfast`, and have to be manually added.
They are currently not part of the `test` or `init` templates.