mirror of https://github.com/status-im/nim-eth.git
split functionality and script
This commit is contained in:
parent
1148f773d1
commit
91862ce65b
|
@ -1,36 +1,7 @@
|
||||||
import strformat, strutils
|
import ./fuzz_helpers
|
||||||
|
|
||||||
# Dependencies:
|
# TODO: get this some nice cmd line options when confutils works for nimscript
|
||||||
# - afl fuzzing: afl and gcc or clang/llvm
|
# or if we want to put this in a nim application instead of script
|
||||||
# - libFuzzer fuzzing: libFuzzer and clang/llvm
|
|
||||||
# - in afl experimental modes clang/llvm is also required
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# - switch clang / gcc option for afl
|
|
||||||
# - afl init and persistent modes
|
|
||||||
# - parallel fuzzing
|
|
||||||
# - custom generate test cases from this script?
|
|
||||||
# - rerun testcases option (or create tests from failed cases)?
|
|
||||||
# - better cmd line parsing & and more options
|
|
||||||
|
|
||||||
const aflGcc = "--cc=gcc " &
|
|
||||||
"--gcc.exe=afl-gcc " &
|
|
||||||
"--gcc.linkerexe=afl-gcc"
|
|
||||||
const aflClang = "--cc=clang " &
|
|
||||||
"--clang.exe=afl-clang " &
|
|
||||||
"--clang.linkerexe=afl-clang"
|
|
||||||
const aflClangFast = "--cc=clang " &
|
|
||||||
"--clang.exe=afl-clang-fast " &
|
|
||||||
"--clang.linkerexe=afl-clang-fast"
|
|
||||||
const libFuzzerClang = "--cc=clang " &
|
|
||||||
"--passC='-fsanitize=fuzzer,address' " &
|
|
||||||
"--passL='-fsanitize=fuzzer,address'"
|
|
||||||
# Can also test in debug mode obviously, but might be slower
|
|
||||||
# Can turn on more logging, in case of libFuzzer it will get very verbose though
|
|
||||||
const defaultFlags = "-d:release -d:chronicles_log_level=fatal " &
|
|
||||||
"--hints:off --warnings:off --verbosity:0"
|
|
||||||
const inputDir = "input" # dir for input samples
|
|
||||||
const resultsDir = "results" # results dir (for afl)
|
|
||||||
|
|
||||||
if paramCount() < 3:
|
if paramCount() < 3:
|
||||||
echo "Usage: nim fuzz.nims FUZZER TARGET"
|
echo "Usage: nim fuzz.nims FUZZER TARGET"
|
||||||
|
@ -45,43 +16,11 @@ if not fileExists(targetPath):
|
||||||
echo "Target file does not exist"
|
echo "Target file does not exist"
|
||||||
quit 1
|
quit 1
|
||||||
|
|
||||||
let splitFile = targetPath.rsplit("/", 1)
|
|
||||||
let workDir = splitFile[0]
|
|
||||||
let targetNimFile = splitFile[1]
|
|
||||||
var target = targetNimFile
|
|
||||||
target.removeSuffix(".nim")
|
|
||||||
cd workDir
|
|
||||||
|
|
||||||
case fuzzer
|
case fuzzer
|
||||||
of "afl":
|
of "afl":
|
||||||
let aflOptions = &"-d:afl -d:noSignalHandler {aflGcc}"
|
runFuzzer(targetPath, afl)
|
||||||
let compileCmd = &"nim c {defaultFlags} {aflOptions} {target}"
|
|
||||||
exec compileCmd
|
|
||||||
|
|
||||||
if not dirExists(inputDir):
|
|
||||||
# create a input dir with one 0 file for afl
|
|
||||||
mkDir(inputDir)
|
|
||||||
withDir inputDir: exec "echo '0' > test"
|
|
||||||
|
|
||||||
var fuzzCmd: string
|
|
||||||
# if there is an output dir already, continue fuzzing from previous run
|
|
||||||
if not dirExists(resultsDir):
|
|
||||||
fuzzCmd = &"afl-fuzz -i {inputDir} -o {resultsDir} -M fuzzer01 -- ./{target}"
|
|
||||||
else:
|
|
||||||
fuzzCmd = &"afl-fuzz -i - -o {resultsDir} -M fuzzer01 -- ./{target}"
|
|
||||||
exec fuzzCmd
|
|
||||||
|
|
||||||
of "libFuzzer":
|
of "libFuzzer":
|
||||||
let libFuzzerOptions = &"--noMain {libFuzzerClang}"
|
runFuzzer(targetPath, libFuzzer)
|
||||||
let compileCmd = &"nim c {defaultFlags} {libFuzzerOptions} {target}"
|
|
||||||
exec compileCmd
|
|
||||||
|
|
||||||
if not dirExists(inputDir):
|
|
||||||
# libFuzzer is OK with empty input dir
|
|
||||||
mkDir(inputDir)
|
|
||||||
|
|
||||||
# TODO: could use {resultsDir} of afl here also to reuse as corpus
|
|
||||||
exec &"./{target} {inputDir}"
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
echo "Invalid fuzzer option: ", fuzzer
|
echo "Invalid fuzzer option: ", fuzzer
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
import strformat, strutils
|
||||||
|
|
||||||
|
# Dependencies:
|
||||||
|
# - afl fuzzing: afl and gcc or clang/llvm
|
||||||
|
# - libFuzzer fuzzing: libFuzzer and clang/llvm
|
||||||
|
# - in afl experimental modes clang/llvm is also required
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# - switch clang / gcc option for afl
|
||||||
|
# - afl init and persistent modes
|
||||||
|
# - parallel fuzzing options
|
||||||
|
# - custom generate test cases from this script?
|
||||||
|
# - rerun testcases option (or create tests from failed cases)
|
||||||
|
# - currently not cross platform
|
||||||
|
# - ...
|
||||||
|
|
||||||
|
const
|
||||||
|
aflGcc = "--cc=gcc " &
|
||||||
|
"--gcc.exe=afl-gcc " &
|
||||||
|
"--gcc.linkerexe=afl-gcc"
|
||||||
|
aflClang = "--cc=clang " &
|
||||||
|
"--clang.exe=afl-clang " &
|
||||||
|
"--clang.linkerexe=afl-clang"
|
||||||
|
aflClangFast = "--cc=clang " &
|
||||||
|
"--clang.exe=afl-clang-fast " &
|
||||||
|
"--clang.linkerexe=afl-clang-fast"
|
||||||
|
libFuzzerClang = "--cc=clang " &
|
||||||
|
"--passC='-fsanitize=fuzzer,address' " &
|
||||||
|
"--passL='-fsanitize=fuzzer,address'"
|
||||||
|
# Can also test in debug mode obviously, but might be slower
|
||||||
|
# Can turn on more logging, in case of libFuzzer it will get very verbose though
|
||||||
|
defaultFlags = "-d:release -d:chronicles_log_level=fatal "# &
|
||||||
|
# "--hints:off --warnings:off --verbosity:0"
|
||||||
|
|
||||||
|
type
|
||||||
|
Fuzzer* = enum
|
||||||
|
afl,
|
||||||
|
libFuzzer
|
||||||
|
|
||||||
|
Compiler* = enum
|
||||||
|
gcc = aflGcc,
|
||||||
|
clang = aflClang,
|
||||||
|
clangFast = aflClangFast
|
||||||
|
|
||||||
|
proc aflCompile*(target: string, c: Compiler) =
|
||||||
|
let aflOptions = &"-d:standalone -d:noSignalHandler {$c}"
|
||||||
|
let compileCmd = &"nim c {defaultFlags} {aflOptions} {target}"
|
||||||
|
exec compileCmd
|
||||||
|
|
||||||
|
proc aflExec*(target: string, inputDir: string, resultsDir: string,
|
||||||
|
cleanStart = false) =
|
||||||
|
if not dirExists(inputDir):
|
||||||
|
# create a input dir with one 0 file for afl
|
||||||
|
mkDir(inputDir)
|
||||||
|
withDir inputDir: exec "echo '0' > test"
|
||||||
|
|
||||||
|
var fuzzCmd: string
|
||||||
|
# if there is an output dir already, continue fuzzing from previous run
|
||||||
|
if (not dirExists(resultsDir)) or cleanStart:
|
||||||
|
fuzzCmd = &"afl-fuzz -i {inputDir} -o {resultsDir} -M fuzzer01 -- ./{target}"
|
||||||
|
else:
|
||||||
|
fuzzCmd = &"afl-fuzz -i - -o {resultsDir} -M fuzzer01 -- ./{target}"
|
||||||
|
exec fuzzCmd
|
||||||
|
|
||||||
|
proc libFuzzerCompile*(target: string) =
|
||||||
|
let libFuzzerOptions = &"--noMain {libFuzzerClang}"
|
||||||
|
let compileCmd = &"nim c {defaultFlags} {libFuzzerOptions} {target}"
|
||||||
|
exec compileCmd
|
||||||
|
|
||||||
|
proc libFuzzerExec*(target: string, corpusDir: string) =
|
||||||
|
if not dirExists(corpusDir):
|
||||||
|
# libFuzzer is OK when starting with empty corpus dir
|
||||||
|
mkDir(corpusDir)
|
||||||
|
|
||||||
|
exec &"./{target} {corpusDir}"
|
||||||
|
|
||||||
|
proc getDir*(path: string): string =
|
||||||
|
# TODO: This is not platform friendly at all.
|
||||||
|
let splitFile = path.rsplit("/", 1)
|
||||||
|
result = splitFile[0]
|
||||||
|
|
||||||
|
proc getTarget*(path: string): string =
|
||||||
|
# TODO: error handling
|
||||||
|
result = path
|
||||||
|
result.removeSuffix(".nim")
|
||||||
|
|
||||||
|
proc runFuzzer*(targetPath: string, fuzzer: Fuzzer) =
|
||||||
|
let
|
||||||
|
path = getDir(targetPath)
|
||||||
|
target = getTarget(targetPath)
|
||||||
|
case fuzzer
|
||||||
|
of afl:
|
||||||
|
aflCompile(targetPath, gcc)
|
||||||
|
aflExec(target, path & "/input", path & "/results")
|
||||||
|
|
||||||
|
of libFuzzer:
|
||||||
|
libFuzzerCompile(targetPath)
|
||||||
|
# Note: Lets not mix afl input with libFuzzer corpus default. This can have
|
||||||
|
# consequences on speed for afl. Better to look into merging afl results &
|
||||||
|
# libFuzzer corpus.
|
||||||
|
libFuzzerExec(target, path & "/corpus")
|
Loading…
Reference in New Issue