2019-10-01 10:00:20 +00:00
|
|
|
import streams, posix, strutils, chronicles, macros, stew/ranges/ptr_arith
|
2019-09-03 13:45:26 +00:00
|
|
|
|
2019-09-25 15:02:43 +00:00
|
|
|
template fuzz(body) =
|
2019-09-03 13:45:26 +00:00
|
|
|
# For code we want to fuzz, SIGSEGV is needed on unwanted exceptions.
|
|
|
|
# However, this is only needed when fuzzing with afl.
|
2019-09-30 13:34:11 +00:00
|
|
|
when defined(standalone):
|
2019-09-03 13:45:26 +00:00
|
|
|
try:
|
|
|
|
body
|
|
|
|
except Exception as e:
|
|
|
|
error "Fuzzer input created exception", exception=e.name, trace=e.repr, msg=e.msg
|
|
|
|
discard kill(getpid(), SIGSEGV)
|
|
|
|
else:
|
|
|
|
body
|
|
|
|
|
|
|
|
proc readStdin*(): seq[byte] =
|
|
|
|
# Read input from stdin (fastest for AFL)
|
|
|
|
let s = newFileStream(stdin)
|
|
|
|
if s.isNil:
|
|
|
|
error "Error opening stdin"
|
|
|
|
discard kill(getpid(), SIGSEGV)
|
|
|
|
# We use binary files as with hex we can get lots of "not hex" failures
|
|
|
|
var input = s.readAll()
|
|
|
|
s.close()
|
|
|
|
# Remove newline if it is there
|
|
|
|
input.removeSuffix
|
2019-09-25 15:02:43 +00:00
|
|
|
result = cast[seq[byte]](input)
|
|
|
|
|
|
|
|
proc NimMain() {.importc: "NimMain".}
|
|
|
|
|
2019-10-01 16:11:28 +00:00
|
|
|
# The default init, gets redefined when init template is used.
|
|
|
|
template initImpl(): untyped =
|
|
|
|
when defined(standalone):
|
|
|
|
discard
|
|
|
|
else:
|
|
|
|
proc fuzzerInit(): cint {.exportc: "LLVMFuzzerInitialize".} =
|
|
|
|
NimMain()
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
template init*(body: untyped) =
|
|
|
|
when defined(standalone):
|
|
|
|
template initImpl(): untyped = fuzz: `body`
|
|
|
|
else:
|
|
|
|
template initImpl() =
|
|
|
|
proc fuzzerInit(): cint {.exportc: "LLVMFuzzerInitialize".} =
|
|
|
|
NimMain()
|
|
|
|
|
|
|
|
`body`
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
2019-09-25 15:16:35 +00:00
|
|
|
template test*(body: untyped): untyped =
|
2019-10-01 16:11:28 +00:00
|
|
|
mixin initImpl
|
|
|
|
initImpl()
|
2019-09-30 13:34:11 +00:00
|
|
|
when defined(standalone):
|
2019-09-25 15:16:35 +00:00
|
|
|
var payload {.inject.} = readStdin()
|
2019-09-25 15:02:43 +00:00
|
|
|
|
2019-09-25 15:16:35 +00:00
|
|
|
fuzz: `body`
|
2019-09-25 15:02:43 +00:00
|
|
|
else:
|
2019-09-25 15:16:35 +00:00
|
|
|
proc fuzzerCall(data: ptr byte, len: csize):
|
|
|
|
cint {.exportc: "LLVMFuzzerTestOneInput".} =
|
2019-10-01 10:00:20 +00:00
|
|
|
template payload(): auto =
|
|
|
|
makeOpenArray(data, len)
|
2019-09-25 15:16:35 +00:00
|
|
|
|
|
|
|
`body`
|