Implement nfuzz_block_header nfuzz_attester_slashing harnesses.

Add notes where not certain whether the error should crash or return
false.

Update header.
This commit is contained in:
Nathaniel Jensen 2019-12-17 15:50:47 +11:00 committed by zah
parent 5978f09261
commit a08db4b311
2 changed files with 91 additions and 29 deletions

View File

@ -12,9 +12,13 @@ extern "C" {
void NimMain();
/** Supported fuzzing tests */
bool nfuzz_attestation(uint8_t* input_ptr, size_t input_size,
uint8_t* output_ptr, size_t* output_size);
bool nfuzz_attester_slashing(uint8_t* input_ptr, size_t input_size,
uint8_t* output_ptr, size_t* output_size);
bool nfuzz_block(uint8_t* input_ptr, size_t input_size,
uint8_t* output_ptr, size_t* output_size);
bool nfuzz_attestation(uint8_t* input_ptr, size_t input_size,
bool nfuzz_block_header(uint8_t* input_ptr, size_t input_size,
uint8_t* output_ptr, size_t* output_size);
bool nfuzz_shuffle(uint8_t* seed_ptr, uint64_t* output_ptr, size_t output_size);

View File

@ -1,7 +1,7 @@
import
endians, stew/ptrops, stew/ranges/ptr_arith,
../beacon_chain/[ssz, state_transition],
../beacon_chain/spec/[datatypes, helpers, digest, validator, beaconstate],
../beacon_chain/spec/[datatypes, helpers, digest, validator, beaconstate, state_transition_block],
# Required for deserialisation of ValidatorSig in Attestation due to
# https://github.com/nim-lang/Nim/issues/11225
../beacon_chain/spec/crypto
@ -10,6 +10,10 @@ type
BlockInput = object
state: BeaconState
beaconBlock: BeaconBlock
BlockHeaderInput = BlockInput
AttesterSlashingInput = object
state: BeaconState
attesterSlashing: AttesterSlashing
AttestationInput = object
state: BeaconState
attestation: Attestation
@ -43,33 +47,6 @@ proc copyState(state: BeaconState, output: ptr byte,
copyMem(output, unsafeAddr resultState[0], output_size[])
result = true
proc nfuzz_block(input: openArray[byte], output: ptr byte,
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
var data: BlockInput
try:
data = SSZ.decode(input, BlockInput)
except MalformedSszError, SszSizeMismatchError:
let e = getCurrentException()
raise newException(FuzzCrashError, "SSZ deserialisation failed, likely bug in preprocessing.", e)
try:
result = state_transition(data.state, data.beaconBlock, flags = {})
except IOError as e:
# TODO why an IOError?
raise newException(FuzzCrashError, "Unexpected IOError in state transition", e)
except Exception as e:
# TODO why an Exception?
# Lots of vendor code looks like it might raise straight exceptions
raise newException(FuzzCrashError, "Unexpected IOError in state transition", e)
except ValueError:
# TODO is a ValueError indicative of correct or incorrect processing code?
# If correct (but given invalid input), we should return false
# If incorrect, we should allow it to crash
result = false
if result:
result = copyState(data.state, output, output_size)
proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
@ -95,6 +72,87 @@ proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
if result:
result = copyState(data.state, output, output_size)
proc nfuzz_attester_slashing(input: openArray[byte], output: ptr byte,
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
var
data: AttesterSlashingInput
cache = get_empty_per_epoch_cache()
try:
data = SSZ.decode(input, AttesterSlashingInput)
except MalformedSszError, SszSizeMismatchError:
let e = getCurrentException()
raise newException(FuzzCrashError, "SSZ deserialisation failed, likely bug in preprocessing.", e)
try:
result = process_attester_slashing(data.state, data.attesterSlashing, cache)
except ValueError:
# TODO is a ValueError indicative of correct or incorrect processing code?
# If correct (but given invalid input), we should return false
# If incorrect, we should allow it to crash
result = false
if result:
result = copyState(data.state, output, output_size)
proc nfuzz_block(input: openArray[byte], output: ptr byte,
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
var data: BlockInput
try:
data = SSZ.decode(input, BlockInput)
except MalformedSszError, SszSizeMismatchError:
let e = getCurrentException()
raise newException(FuzzCrashError, "SSZ deserialisation failed, likely bug in preprocessing.", e)
try:
result = state_transition(data.state, data.beaconBlock, flags = {})
except IOError as e:
# TODO why an IOError?
raise newException(FuzzCrashError, "Unexpected IOError in state transition", e)
except Exception as e:
# TODO why an Exception?
# Lots of vendor code looks like it might raise a bare exception type
raise newException(FuzzCrashError, "Unexpected IOError in state transition", e)
except ValueError:
# TODO is a ValueError indicative of correct or incorrect processing code?
# If correct (but given invalid input), we should return false
# If incorrect, we should allow it to crash
result = false
if result:
result = copyState(data.state, output, output_size)
proc nfuzz_block_header(input: openArray[byte], output: ptr byte,
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
var
data: BlockHeaderInput
cache = get_empty_per_epoch_cache()
try:
data = SSZ.decode(input, BlockHeaderInput)
except MalformedSszError, SszSizeMismatchError:
let e = getCurrentException()
raise newException(FuzzCrashError, "SSZ deserialisation failed, likely bug in preprocessing.", e)
try:
result = process_block_header(data.state, data.beaconBlock, flags = {}, cache)
except IOError as e:
# TODO why an IOError? - is this expected/should we return false?
raise newException(FuzzCrashError, "Unexpected IOError in block header processing", e)
except ValueError:
# TODO is a ValueError indicative of correct or incorrect processing code?
# If correct (but given invalid input), we should return false
# If incorrect, we should allow it to crash
result = false
if result:
result = copyState(data.state, output, output_size)
# Note: Could also accept raw input pointer and access list_size + seed here.
# However, list_size needs to be known also outside this proc to allocate output.
# TODO: rework to copy immediatly in an uint8 openArray, considering we have to