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

[crash/fuzzing] "java.lang.IndexOutOfBoundsException: index (0) must be less than size (0)" during block ssz parsing #1685

Closed
pventuzelo opened this issue Apr 28, 2020 · 1 comment · Fixed by #1693

Comments

@pventuzelo
Copy link

Description

During fuzzing with beacon-fuzz, I triggered an java.lang.IndexOutOfBoundsException: index (0) must be less than size (0) during block SSZ parsing using teku transition blocks tool.

** bug come from bits.getBit(i) line 121**

Additional info

lighthouse detects this bug and returns:

Failed to transition blocks: Failed to advance slot on iteration 95: EpochProcessingError(BeaconStateError(InvalidBitfield))

Related code:

https://github.com/PegaSysEng/teku/blob/f79f65fdc23414dd08d2e0c5d93211df3fa52665/ethereum/datastructures/src/main/java/tech/pegasys/artemis/datastructures/util/AttestationUtil.java#L114-L124

Steps to Reproduce (Bug)

# install
./gradlew distTar installDist

# go to build folder
cd build/install/

# Run teku
bin/teku transition blocks --pre=index_less_size_oob_state_teku.ssz --network=mainnet index_less_size_oob_block_teku.ssz
java.lang.IndexOutOfBoundsException: index (0) must be less than size (0)
	at com.google.common.base.Preconditions.checkElementIndex(Preconditions.java:1345)
	at com.google.common.base.Preconditions.checkElementIndex(Preconditions.java:1327)
	at tech.pegasys.artemis.ssz.SSZTypes.Bitlist.getBit(Bitlist.java:55)
	at tech.pegasys.artemis.datastructures.util.AttestationUtil.get_attesting_indices(AttestationUtil.java:121)
	at tech.pegasys.artemis.core.EpochProcessorUtil.get_unslashed_attesting_indices(EpochProcessorUtil.java:165)
	at tech.pegasys.artemis.core.EpochProcessorUtil.get_unslashed_attesting_indices(EpochProcessorUtil.java:156)
	at tech.pegasys.artemis.core.EpochProcessorUtil.get_attesting_balance(EpochProcessorUtil.java:186)
	at tech.pegasys.artemis.core.EpochProcessorUtil.process_justification_and_finalization(EpochProcessorUtil.java:227)
	at tech.pegasys.artemis.core.StateTransition.lambda$process_epoch$1(StateTransition.java:145)
	at tech.pegasys.artemis.datastructures.state.BeaconStateImpl.updated(BeaconStateImpl.java:273)
	at tech.pegasys.artemis.core.StateTransition.process_epoch(StateTransition.java:142)
	at tech.pegasys.artemis.core.StateTransition.process_slots(StateTransition.java:215)
	at tech.pegasys.artemis.core.StateTransition.initiate(StateTransition.java:94)
	at tech.pegasys.artemis.core.StateTransition.initiate(StateTransition.java:72)
	at tech.pegasys.artemis.cli.subcommand.TransitionCommand.lambda$blocks$0(TransitionCommand.java:82)
	at tech.pegasys.artemis.cli.subcommand.TransitionCommand.processStateTransition(TransitionCommand.java:131)
	at tech.pegasys.artemis.cli.subcommand.TransitionCommand.blocks(TransitionCommand.java:76)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at picocli.CommandLine.executeUserObject(CommandLine.java:1802)
	at picocli.CommandLine.access$900(CommandLine.java:145)
	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2150)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2144)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2108)
	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:1975)
	at picocli.CommandLine.execute(CommandLine.java:1904)
	at tech.pegasys.artemis.cli.BeaconNodeCommand.parse(BeaconNodeCommand.java:185)
	at tech.pegasys.artemis.Artemis.main(Artemis.java:31)

Versions

  • Github branch: master
  • Github commit: 1cc3466
  • Java version: openjdk version "11.0.7" 2020-04-14
  • OS Name & Version: Ubuntu 18.04.4 LTS
  • Kernel Version: 4.15.0-96-generic
@ajsutton
Copy link
Contributor

The SSZ in this case is valid, but the initial state contains pending attestations where the aggregation bits size is less than the committee size. The transition subcommand doesn't do any validation on the input state so I wouldn't expect it to detect that. In a running Teku the IndexOutOfBoundsException is caught and the bock import would fail but it does highlight some areas lacking validation around ensuring that the aggregation bit size matches the committee size. Block import does it, fork choice required it to be at least as big but gossip validation missed it.

I've tidied that up, but my reading of the fork choice spec suggests that it misses this case as well and never validates that the attestation's aggregation bits matches the committee size.

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.

2 participants