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,7 +329,10 @@ proc rlpHash*[T](v: T): Hash256 =
func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h) func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
proc notImplemented = proc notImplemented =
doAssert false, "Method not implemented" when defined(afl) or defined(libFuzzer):
discard
else:
doAssert false, "Method not implemented"
template hasData*(b: Blob): bool = b.len > 0 template hasData*(b: Blob): bool = b.len > 0
template hasData*(r: EthResourceRefs): bool = r != nil template hasData*(r: EthResourceRefs): bool = r != nil

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import streams, posix, strutils, chronicles, macros, stew/ranges/ptr_arith
template fuzz(body) = template fuzz(body) =
# For code we want to fuzz, SIGSEGV is needed on unwanted exceptions. # For code we want to fuzz, SIGSEGV is needed on unwanted exceptions.
# However, this is only needed when fuzzing with afl. # However, this is only needed when fuzzing with afl.
when defined(standalone): when defined(afl):
try: try:
body body
except Exception as e: except Exception as e:
@ -29,7 +29,7 @@ proc NimMain() {.importc: "NimMain".}
# The default init, gets redefined when init template is used. # The default init, gets redefined when init template is used.
template initImpl(): untyped = template initImpl(): untyped =
when defined(standalone): when not defined(libFuzzer):
discard discard
else: else:
proc fuzzerInit(): cint {.exportc: "LLVMFuzzerInitialize".} = 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 ## 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 ## stateless or make sure everything gets properply reset for each new run in
## the test block. ## the test block.
when defined(standalone): when not defined(libFuzzer):
template initImpl(): untyped = fuzz: `body` template initImpl(): untyped = fuzz: `body`
else: else:
template initImpl() = template initImpl() =
@ -64,7 +64,7 @@ template test*(body: untyped): untyped =
## contains the payload provided by the fuzzer. ## contains the payload provided by the fuzzer.
mixin initImpl mixin initImpl
initImpl() initImpl()
when defined(standalone): when not defined(libFuzzer):
var payload {.inject.} = readStdin() var payload {.inject.} = readStdin()
fuzz: `body` fuzz: `body`
@ -76,8 +76,6 @@ template test*(body: untyped): untyped =
`body` `body`
# var aflClangFast {.importc: "__AFL_HAVE_MANUAL_CONTROL", noDecl.}: int
when defined(clangfast): when defined(clangfast):
## Can be used for deferred instrumentation. ## Can be used for deferred instrumentation.
## Should be placed on a suitable location in the code where the delayed ## 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 #### Compiling
With gcc: With gcc:
```sh ```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. templates.
You typically want to fuzz in `-d:release` and probably also want to lower down 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: With clang:
```sh ```sh
# afl-clang # 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 # 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 #### Starting the Fuzzer
@ -135,17 +135,26 @@ afl-fuzz -i input -o results -S fuzzer03 -- ./testcase
# add more if needed # 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.: manually by providing it input data, e.g.:
```sh ```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 ### Manually with libFuzzer
#### Compiling #### Compiling
```sh ```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 You typically want to fuzz in `-d:release` and probably also want to lower down
the logging. But this is not strictly necessary. 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 run before each test block, compared to libFuzzer, where it will be run only
once. once.
In case of using afl with `alf-clang-fast` you can make use of `aflInit()` and In case of using afl with `alf-clang-fast` you can make use of `aflInit()` proc
`aflLoop()` calls. and `aflLoop()` template.
`aflInit()` will allow using what is called deferred instrumentation. Basically, `aflInit()` will allow using what is called deferred instrumentation. Basically,
the forking of the process will only happen after this call, where normally it the forking of the process will only happen after this call, where normally it
is done right before `main()`. is done right before `main()`.
`aflLoop(cint)` will allow for (experimental) persistant mode. This is more `aflLoop:` will allow for (experimental) persistant mode. It will run the test
comparable with libFuzzer. 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.