mirror of https://github.com/status-im/nim-eth.git
Remove standalone define and add specific afl/libFuzzer define
This commit is contained in:
parent
9ee208876d
commit
757ac1ab86
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue