updated timeout to run in thread to fix unsafe exception handling #107
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When trying to make a chain for a specific binary, we 100% reliably get this exception:
This is an angrop timeout which is interrupting some z3 code to throw an exception.
What's specifically happening here is that the z3 code that's being interrupted to inject a RopException is a
__del__
method.Here's an excerpt from:
https://docs.python.org/3/reference/datamodel.html#object.__del__
According to Python documentation, when an Exception is raised under a
__del__
method, the Exception is ignored and execution continues.So, in our specific scenario, the timeout fails and analysis continues until you run out of RAM and the OOM Killer kills your python process.
I've included a script called orig_timeout.py to demonstrate this. The script calls busy_function() which takes about 3 seconds to run. I copied the angrop timeout decorator into the script and forced the busy_function to have a 1 second timeout. You can see from running the script that busy_function() receives the timeout exception at the 1 second mark, but since it's executing a
__del__
method, the exception is ignored and busy_function continues executing until it is finished.I've also included another script called new_timeout.py. This is a proposed new timeout solution. It kicks off the decorated function in a thread. When the timeout fires, a RopException is remotely raised in the target thread. If the target thread is currently executing a
__del__
method, the exception will be ignored (can't get around this behavior). However, we can see the thread is still running, so the timeout decorator will send RopExceptions to the target thread every 100ms until the exception takes effect in the target thread.py_files.zip