mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-18 10:31:04 +00:00
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:
parent
5978f09261
commit
a08db4b311
@ -12,9 +12,13 @@ extern "C" {
|
|||||||
void NimMain();
|
void NimMain();
|
||||||
|
|
||||||
/** Supported fuzzing tests */
|
/** 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,
|
bool nfuzz_block(uint8_t* input_ptr, size_t input_size,
|
||||||
uint8_t* output_ptr, size_t* output_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);
|
uint8_t* output_ptr, size_t* output_size);
|
||||||
bool nfuzz_shuffle(uint8_t* seed_ptr, uint64_t* output_ptr, size_t output_size);
|
bool nfuzz_shuffle(uint8_t* seed_ptr, uint64_t* output_ptr, size_t output_size);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import
|
import
|
||||||
endians, stew/ptrops, stew/ranges/ptr_arith,
|
endians, stew/ptrops, stew/ranges/ptr_arith,
|
||||||
../beacon_chain/[ssz, state_transition],
|
../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
|
# Required for deserialisation of ValidatorSig in Attestation due to
|
||||||
# https://github.com/nim-lang/Nim/issues/11225
|
# https://github.com/nim-lang/Nim/issues/11225
|
||||||
../beacon_chain/spec/crypto
|
../beacon_chain/spec/crypto
|
||||||
@ -10,6 +10,10 @@ type
|
|||||||
BlockInput = object
|
BlockInput = object
|
||||||
state: BeaconState
|
state: BeaconState
|
||||||
beaconBlock: BeaconBlock
|
beaconBlock: BeaconBlock
|
||||||
|
BlockHeaderInput = BlockInput
|
||||||
|
AttesterSlashingInput = object
|
||||||
|
state: BeaconState
|
||||||
|
attesterSlashing: AttesterSlashing
|
||||||
AttestationInput = object
|
AttestationInput = object
|
||||||
state: BeaconState
|
state: BeaconState
|
||||||
attestation: Attestation
|
attestation: Attestation
|
||||||
@ -43,33 +47,6 @@ proc copyState(state: BeaconState, output: ptr byte,
|
|||||||
copyMem(output, unsafeAddr resultState[0], output_size[])
|
copyMem(output, unsafeAddr resultState[0], output_size[])
|
||||||
result = true
|
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,
|
proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
|
||||||
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
|
output_size: ptr uint): bool {.exportc, raises:[FuzzCrashError, Defect].} =
|
||||||
@ -95,6 +72,87 @@ proc nfuzz_attestation(input: openArray[byte], output: ptr byte,
|
|||||||
if result:
|
if result:
|
||||||
result = copyState(data.state, output, output_size)
|
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.
|
# 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.
|
# 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
|
# TODO: rework to copy immediatly in an uint8 openArray, considering we have to
|
||||||
|
Loading…
x
Reference in New Issue
Block a user