Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fuzzing] Illegal Index Array Access in Attester Slashing Processing #2345

Closed
zedt3ster opened this issue Jul 13, 2020 · 1 comment · Fixed by #2348
Closed

[Fuzzing] Illegal Index Array Access in Attester Slashing Processing #2345

zedt3ster opened this issue Jul 13, 2020 · 1 comment · Fixed by #2348

Comments

@zedt3ster
Copy link

Description

While fuzzing Teku's Attester Slashing processing using beacon-fuzz, I triggered the following exception:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1953788990 out of bounds for length 256

Note that this was triggered using a valid BeaconState, and the related AttesterSlashing SSZ container can be successfully parsed using zcli.

From a quick glance, the affected code seems to be:

https://github.com/PegaSysEng/teku/blob/d9fdf128e70b7cc4d5d0b556f1bea20f17b7bf22/ssz/src/main/java/tech/pegasys/teku/ssz/backing/cache/ArrayIntCache.java#L68-L76

Steps to Reproduce (Bug)

  • The related BeaconState and AttesterSlashing containers can be downloaded here.

We have a small utility to reproduce this bug, as part of eth2fuzz:

  • Follow the instructions to set up a Teku eth2fuzz docker container, described here (i.e. make teku).
  • Drop the two files from the archive above in beacon-fuzz/eth2fuzz/workspace/javafuzz
  • Get a shell inside the docker container (must be ran from the eth2fuzz directory):
    docker run -v $(pwd)/workspace:/eth2fuzz/workspace --entrypoint=bash -it eth2fuzz_teku
  • Move to the right directory and build the utility: cd workspace/javafuzz/ && javac -cp .:$(./tekuclass.sh) TekuFuzz.java
  • Run the debugging tool: DEBUG_BEACONSTATE=beaconstate.ssz DEBUG_CONTAINER=ssz3.ssz CLASSPATH=$CLASSPATH:$(./tekuclass.sh) java TekuFuzz
  • Observe the crash:
[+] beaconstate ok
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1953788990 out of bounds for length 256
	at tech.pegasys.teku.ssz.backing.cache.ArrayIntCache.getInt(ArrayIntCache.java:70)
	at tech.pegasys.teku.ssz.backing.view.AbstractCompositeViewRead.get(AbstractCompositeViewRead.java:87)
	at tech.pegasys.teku.ssz.backing.view.AbstractCompositeViewWrite.get(AbstractCompositeViewWrite.java:86)
	at tech.pegasys.teku.ssz.backing.view.AbstractCompositeViewWrite.get(AbstractCompositeViewWrite.java:47)
	at tech.pegasys.teku.ssz.backing.view.ListViewWriteImpl.get(ListViewWriteImpl.java:95)
	at tech.pegasys.teku.ssz.backing.view.ListViewWriteImpl.get(ListViewWriteImpl.java:31)
	at tech.pegasys.teku.ssz.SSZTypes.SSZBackingList.get(SSZBackingList.java:47)
	at tech.pegasys.teku.datastructures.util.ValidatorsUtil.lambda$getValidatorPubKey$0(ValidatorsUtil.java:76)
	at tech.pegasys.teku.util.cache.LRUCache.get(LRUCache.java:73)
	at tech.pegasys.teku.datastructures.util.ValidatorsUtil.getValidatorPubKey(ValidatorsUtil.java:76)
	at tech.pegasys.teku.datastructures.util.AttestationUtil.lambda$is_valid_indexed_attestation$0(AttestationUtil.java:159)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at tech.pegasys.teku.datastructures.util.AttestationUtil.is_valid_indexed_attestation(AttestationUtil.java:159)
	at tech.pegasys.teku.datastructures.util.AttestationUtil.is_valid_indexed_attestation(AttestationUtil.java:143)
	at tech.pegasys.teku.core.operationvalidators.AttesterSlashingStateTransitionValidator.lambda$validate$1(AttesterSlashingStateTransitionValidator.java:61)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
	at tech.pegasys.teku.core.operationvalidators.OperationInvalidReason.firstOf(OperationInvalidReason.java:31)
	at tech.pegasys.teku.core.operationvalidators.AttesterSlashingStateTransitionValidator.validate(AttesterSlashingStateTransitionValidator.java:54)
	at tech.pegasys.teku.core.operationvalidators.AttesterSlashingStateTransitionValidator.validate(AttesterSlashingStateTransitionValidator.java:39)
	at tech.pegasys.teku.core.BlockProcessorUtil.process_attester_slashings(BlockProcessorUtil.java:318)
	at TekuFuzz.lambda$teku_attester_slashing$1(TekuFuzz.java:206)
	at tech.pegasys.teku.datastructures.state.BeaconStateImpl.updated(BeaconStateImpl.java:247)
	at TekuFuzz.teku_attester_slashing(TekuFuzz.java:204)
	at TekuFuzz.main(TekuFuzz.java:95)

Versions

  • Github branch: master
  • Commit: d9fdf12
  • Java version: openjdk version "11.0.7" 2020-04-14
  • OS Name & Version: Ubuntu 18.04.4 LTS
@zedt3ster
Copy link
Author

@ajsutton raised that the BeaconState actually used isn't compliant with the latest version of the eth2 spec (v0.12.1). I've reproduced this bug using a BeaconState pulled directly from one of the testnets currently running. For reference, you can find it
here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant