Build fuzzing tests in CI and fix current fuzzing tests (#396)

* Build fuzzing tests in CI and fix current fuzzing tests

* Build fuzzing tests separately (fix Windows CI)
This commit is contained in:
Kim De Mey 2021-09-07 16:00:01 +02:00 committed by GitHub
parent bea1f1c6a1
commit df6020832b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 54 additions and 35 deletions

View File

@ -237,3 +237,4 @@ jobs:
nimble install -y --depsOnly nimble install -y --depsOnly
nimble test nimble test
nimble build_dcli nimble build_dcli
nimble build_fuzzers

View File

@ -90,3 +90,16 @@ task test_discv5_full, "Run discovery v5 and its dependencies tests":
task build_dcli, "Build dcli": task build_dcli, "Build dcli":
buildBinary("eth/p2p/discoveryv5/dcli") buildBinary("eth/p2p/discoveryv5/dcli")
import os, strutils
task build_fuzzers, "Build fuzzer test cases":
# This file is there to be able to quickly build the fuzzer test cases in
# order to avoid bit rot (e.g. for CI). Not for actual fuzzing.
# TODO: Building fuzzer test case one by one will make it take a bit longer,
# but we cannot import them in one Nim file due to the usage of
# `exportc: "AFLmain"` in the fuzzing test template for Windows:
# https://github.com/status-im/nim-testutils/blob/master/testutils/fuzzing.nim#L100
for file in walkDirRec("tests/fuzzing/"):
if file.endsWith("nim"):
buildBinary(file)

View File

@ -6,7 +6,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import import
eth/common/[eth_types, state_accessors] ../common/[eth_types, state_accessors]
# TODO: Perhaps we can move this to eth-common # TODO: Perhaps we can move this to eth-common

View File

@ -1,11 +1,18 @@
import import
testutils/fuzzing, chronicles, testutils/fuzzing, chronicles, nimcrypto/keccak,
eth/p2p/[discovery, enode], eth/[keys, rlp], ../../../eth/p2p/[discovery, enode], ../../../eth/[keys, rlp],
../../p2p/p2p_test_helper ../../p2p/p2p_test_helper
const DefaultListeningPort = 30303 const DefaultListeningPort = 30303
var targetNode: DiscoveryProtocol var targetNode: DiscoveryProtocol
proc packData(payload: openArray[byte], pk: PrivateKey): seq[byte] =
let
payloadSeq = @payload
signature = @(pk.sign(payload).toRaw())
msgHash = keccak256.digest(signature & payloadSeq)
result = @(msgHash.data) & signature & payloadSeq
init: init:
# Set up a discovery node, this is the node we target when fuzzing # Set up a discovery node, this is the node we target when fuzzing
var var

View File

@ -1,17 +1,13 @@
import import
chronos, times, stew/byteutils, stint, chronicles, streams, nimcrypto, os, std/[times, os, strformat, strutils],
strformat, strutils, eth/p2p/[discovery, kademlia], eth/[keys, rlp], chronos, stew/byteutils, stint, chronicles, nimcrypto,
../../p2p/p2p_test_helper ../../../eth/p2p/[discovery, kademlia], ../../../eth/[keys, rlp],
../../p2p/p2p_test_helper,
../fuzzing_helpers
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
const inputsDir = &"{sourceDir}{DirSep}generated-input{DirSep}" const inputsDir = &"{sourceDir}{DirSep}generated-input{DirSep}"
proc toFile(data: Bytes, fn: string) =
var s = newFileStream(fn, fmWrite)
for x in data:
s.write(x)
s.close()
const EXPIRATION = 3600 * 24 * 365 * 10 const EXPIRATION = 3600 * 24 * 365 * 10
proc expiration(): uint32 = uint32(epochTime() + EXPIRATION) proc expiration(): uint32 = uint32(epochTime() + EXPIRATION)
@ -32,7 +28,7 @@ proc generate() =
# valid data for a Pong packet # valid data for a Pong packet
block: block:
let token = keccak256.digest(@[0]) let token = keccak256.digest(@[byte 0])
let payload = rlp.encode((toAddr, token , expiration())) let payload = rlp.encode((toAddr, token , expiration()))
let encodedData = @[2.byte] & payload let encodedData = @[2.byte] & payload
debug "Pong", data=byteutils.toHex(encodedData) debug "Pong", data=byteutils.toHex(encodedData)
@ -42,9 +38,9 @@ proc generate() =
# valid data for a FindNode packet # valid data for a FindNode packet
block: block:
var data: array[64, byte] var data: array[64, byte]
data[32 .. ^1] = peerKey.toPublicKey().tryGet().toNodeId().toByteArrayBE() data[32 .. ^1] = peerKey.toPublicKey().toNodeId().toByteArrayBE()
let payload = rlp.encode((data, expiration())) let payload = rlp.encode((data, expiration()))
let encodedData = @[3.byte] & payload.toSeq() let encodedData = @[3.byte] & @payload
debug "FindNode", data=byteutils.toHex(encodedData) debug "FindNode", data=byteutils.toHex(encodedData)
encodedData.toFile(inputsDir & "findnode") encodedData.toFile(inputsDir & "findnode")
@ -62,11 +58,11 @@ proc generate() =
type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey] type Neighbour = tuple[ip: IpAddress, udpPort, tcpPort: Port, pk: PublicKey]
var nodes = newSeqOfCap[Neighbour](2) var nodes = newSeqOfCap[Neighbour](2)
nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.toPublicKey().tryGet())) nodes.add((n1Addr.ip, n1Addr.udpPort, n1Addr.tcpPort, n1Key.toPublicKey()))
nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.toPublicKey().tryGet())) nodes.add((n2Addr.ip, n2Addr.udpPort, n2Addr.tcpPort, n2Key.toPublicKey()))
let payload = rlp.encode((nodes, expiration())) let payload = rlp.encode((nodes, expiration()))
let encodedData = @[4.byte] & payload.toSeq() let encodedData = @[4.byte] & @payload
debug "Neighbours", data=byteutils.toHex(encodedData) debug "Neighbours", data=byteutils.toHex(encodedData)
encodedData.toFile(inputsDir & "neighbours") encodedData.toFile(inputsDir & "neighbours")

View File

@ -1,6 +1,6 @@
import import
testutils/fuzzing, stew/byteutils, testutils/fuzzing,
eth/rlp, eth/p2p/discoveryv5/[encoding, messages] ../../../eth/rlp, ../../../eth/p2p/discoveryv5/[encoding, messages]
test: test:
block: block:

View File

@ -1,6 +1,6 @@
import import
testutils/fuzzing, stew/shims/net, stew/byteutils, testutils/fuzzing, stew/shims/net,
eth/p2p/discoveryv5/[encoding, enr, sessions, node] ../../../eth/p2p/discoveryv5/[encoding, enr, sessions, node]
init: init:
const const

View File

@ -1,6 +1,6 @@
import import
testutils/fuzzing, stew/byteutils, testutils/fuzzing, stew/byteutils,
eth/rlp, eth/p2p/discoveryv5/enr ../../../eth/rlp, ../../../eth/p2p/discoveryv5/enr
test: test:
block: block:

View File

@ -1,7 +1,7 @@
import import
std/[os, strutils, options], std/[os, strutils, options],
stew/shims/net, stew/shims/net,
eth/keys, eth/p2p/discoveryv5/enr, ../../../eth/keys, ../../../eth/p2p/discoveryv5/enr,
../fuzzing_helpers ../fuzzing_helpers
template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0] template sourceDir: string = currentSourcePath.rsplit(DirSep, 1)[0]
@ -12,7 +12,7 @@ proc generate() =
rng = newRng() rng = newRng()
privKey = PrivateKey.random(rng[]) privKey = PrivateKey.random(rng[])
ip = some(ValidIpAddress.init("127.0.0.1")) ip = some(ValidIpAddress.init("127.0.0.1"))
port = Port(20301) port = some(Port(20301))
block: block:
let record = enr.Record.init(1, privKey, ip, port, port)[] let record = enr.Record.init(1, privKey, ip, port, port)[]

View File

@ -1,5 +1,5 @@
import import
std/streams std/streams
proc toFile*(data: seq[byte], fn: string) = proc toFile*(data: seq[byte], fn: string) =
var s = newFileStream(fn, fmWrite) var s = newFileStream(fn, fmWrite)

View File

@ -1,6 +1,6 @@
import import
testutils/fuzzing, chronicles, testutils/fuzzing, chronicles,
eth/rlp ../../../eth/rlp
type type
TestEnum = enum TestEnum = enum

View File

@ -1,6 +1,6 @@
import import
testutils/fuzzing, chronicles, testutils/fuzzing, chronicles,
eth/rlp ../../../eth/rlp
test: test:
try: try:

View File

@ -1,8 +1,8 @@
import import
testutils/fuzzing, chronos, testutils/fuzzing, chronos,
eth/p2p, eth/p2p/rlpx, eth/p2p/private/p2p_types, ../../../eth/p2p, ../../../eth/p2p/rlpx, ../../../eth/p2p/private/p2p_types,
eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol], ../../../eth/p2p/rlpx_protocols/[whisper_protocol, eth_protocol],
../p2p/p2p_test_helper ../../p2p/p2p_test_helper
var var
node1: EthereumNode node1: EthereumNode

View File

@ -1,13 +1,15 @@
import import
options, sequtils, chronicles, std/[options, sequtils],
eth/p2p/rlpx_protocols/whisper_protocol as whisper, chronicles, testutils/fuzzing,
../fuzztest ../../../eth/p2p/rlpx_protocols/whisper_protocol as whisper,
../../../eth/keys
test: test:
let let
rng = newRng()
data = @payload.distribute(2) data = @payload.distribute(2)
whisperPayload = Payload(payload: data[0], padding: some(data[1])) whisperPayload = Payload(payload: data[0], padding: some(data[1]))
encoded = whisper.encode(whisperPayload) encoded = whisper.encode(rng[], whisperPayload)
decoded = whisper.decode(encoded.get()) decoded = whisper.decode(encoded.get())