From 39e57b6725f38fa6738a109a83f4d273cdb80ede Mon Sep 17 00:00:00 2001 From: Joe Ranweiler Date: Fri, 16 Feb 2018 11:41:55 -0800 Subject: [PATCH] Be stricter about what terminated states are saved as crashes We only want to save a `.crash` file if the input would cause a crash when executing using the native harness. The old impl treated any state termination as a crash. Now we add a predicate which checks the `reason` and decides if the termination represents a crash in the program being analyzed. For now, we only flag `InvalidMemoryAccess` exceptions as crashes, as identified by the `message` property on a `TerminateState` exception. --- bin/deepstate/main_manticore.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/bin/deepstate/main_manticore.py b/bin/deepstate/main_manticore.py index b2aa623..5c8fcbd 100644 --- a/bin/deepstate/main_manticore.py +++ b/bin/deepstate/main_manticore.py @@ -243,14 +243,39 @@ def hook(func): return lambda state: state.invoke_model(func) +def _is_program_crash(reason): + """Using the `reason` for the termination of a Manticore `will_terminate_state` + event, decide if we want to treat the termination as a "crash" of the program + being analyzed.""" + + if not isinstance(reason, TerminateState): + return False + + return 'Invalid memory access' in reason.message + + def done_test(_, state, state_id, reason): """Called when a state is terminated.""" mc = DeepManticore(state) + # Note that `reason` is either an `Exception` or a `str`. If it is the special + # `OUR_TERMINATION_REASON`, then the state was terminated via a hook into the + # DeepState API, so we can just report it as is. Otherwise, we check to see if + # it was due to behavior that would typically crash the program being analyzed. + # If so, we save it as a crash. If not, we abandon it. if OUR_TERMINATION_REASON not in reason: - L.info("State {} terminated for unknown reason, treating as crash: {}".format( - state_id, reason)) - super(DeepManticore, mc).crash_test() + if _is_program_crash(reason): + L.info("State {} terminated due to crashing program behavior: {}".format( + state_id, reason)) + + # Don't raise new `TerminateState` exception + super(DeepManticore, mc).crash_test() + else: + L.error("State {} terminated due to internal error: {}".format(state_id, + reason)) + + # Don't raise new `TerminateState` exception + super(DeepManticore, mc).abandon_test() mc.report()