Merge pull request #853 from nbanmp/timeout

Implement sigalrm timeout
pull/863/head
Nathan 6 years ago committed by GitHub
commit 1a7d8c679c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      mythril/alarm.py
  2. 4
      mythril/exceptions.py
  3. 63
      mythril/laser/ethereum/svm.py

@ -0,0 +1,25 @@
import signal
from types import FrameType
from mythril.exceptions import OutOfTimeError
def sigalrm_handler(signum: int, frame: FrameType) -> None:
raise OutOfTimeError
def start_timeout(timeout: int) -> None:
"""
Starts a timeout
:param timeout: Time in seconds to set the timeout for
:return: None
"""
signal.signal(signal.SIGALRM, sigalrm_handler)
signal.alarm(timeout)
def disable_timeout() -> None:
"""
Ensures that the timeout is disabled
:return: None
"""
signal.alarm(0)

@ -2,6 +2,10 @@ class MythrilBaseException(Exception):
pass
class OutOfTimeError(MythrilBaseException):
pass
class CompilerError(MythrilBaseException):
pass

@ -5,6 +5,8 @@ from datetime import datetime, timedelta
from functools import reduce
from typing import List, Tuple, Union, Callable, Dict
from mythril import alarm
from mythril.exceptions import OutOfTimeError
from mythril.laser.ethereum.cfg import NodeFlags, Node, Edge, JumpType
from mythril.laser.ethereum.evm_exceptions import StackUnderflowException
from mythril.laser.ethereum.evm_exceptions import VmException
@ -67,7 +69,7 @@ class LaserEVM:
self.max_depth = max_depth
self.transaction_count = transaction_count
self.execution_timeout = execution_timeout
self.execution_timeout = execution_timeout or 0
self.create_timeout = create_timeout
self.requires_statespace = requires_statespace
@ -103,29 +105,37 @@ class LaserEVM:
self, main_address=None, creation_code=None, contract_name=None
) -> None:
log.debug("Starting LASER execution")
self.time = datetime.now()
if main_address:
log.info("Starting message call transaction to {}".format(main_address))
self._execute_transactions(main_address)
try:
alarm.start_timeout(self.execution_timeout)
self.time = datetime.now()
elif creation_code:
log.info("Starting contract creation transaction")
created_account = execute_contract_creation(
self, creation_code, contract_name
)
log.info(
"Finished contract creation, found {} open states".format(
len(self.open_states)
if main_address:
log.info("Starting message call transaction to {}".format(main_address))
self._execute_transactions(main_address)
elif creation_code:
log.info("Starting contract creation transaction")
created_account = execute_contract_creation(
self, creation_code, contract_name
)
)
if len(self.open_states) == 0:
log.warning(
"No contract was created during the execution of contract creation "
"Increase the resources for creation execution (--max-depth or --create-timeout)"
log.info(
"Finished contract creation, found {} open states".format(
len(self.open_states)
)
)
if len(self.open_states) == 0:
log.warning(
"No contract was created during the execution of contract creation "
"Increase the resources for creation execution (--max-depth or --create-timeout)"
)
self._execute_transactions(created_account.address)
self._execute_transactions(created_account.address)
except OutOfTimeError:
log.warning("Timeout occurred, ending symbolic execution")
finally:
alarm.disable_timeout()
log.info("Finished symbolic execution")
if self.requires_statespace:
@ -181,15 +191,12 @@ class LaserEVM:
def exec(self, create=False, track_gas=False) -> Union[List[GlobalState], None]:
final_states = []
for global_state in self.strategy:
if self.execution_timeout and not create:
if (
self.time + timedelta(seconds=self.execution_timeout)
<= datetime.now()
):
return final_states + [global_state] if track_gas else None
elif self.create_timeout and create:
if self.time + timedelta(seconds=self.create_timeout) <= datetime.now():
return final_states + [global_state] if track_gas else None
if (
self.create_timeout
and create
and self.time + timedelta(seconds=self.create_timeout) <= datetime.now()
):
return final_states + [global_state] if track_gas else None
try:
new_states, op_code = self.execute_state(global_state)

Loading…
Cancel
Save