-
Notifications
You must be signed in to change notification settings - Fork 478
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
Optimise forking when there is only 1 solution #2527
Conversation
5868f33
to
244844a
Compare
bdad132
to
34850ea
Compare
34850ea
to
958bb80
Compare
I added a test for forking on a unique solution. |
this PR helps with latest python3.9.9 on gentoo, one can successfully use manticore on a contract |
@Kokokokoka: would you mind elaborating on your comment? Does this PR fix an opened issue, or just a bug that you was running into but didn't report? |
I've seen similar bug reports #2518 seems to be the same, maybe there were others (which had mac os in them). I had this bug both on mac m1 and on my gentoo pc. Now it works |
The implementation looks good to me! Once we clarify my final question on the model tests I'm happy to approve & merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, submitting via github.dev dropped all my comments, so let's try that again
tests/native/test_models.py
Outdated
m.finalize() | ||
|
||
# Expected stdout outputs | ||
expected = {"Length of string is: 0", "Length of string is: 1"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we expect to see different results for this test before the changes to our forking strategy? If we're forking on the length of the string, and constrain the second byte to be zero, then it makes sense that valid strings would be of length zero or one. That's two possibilities, which doesn't seem like it would test the new forking policy.
Would it make more sense to inspect the fork events using a plugin, or inspect the state ID numbers to confirm that we aren't creating new states when we concretize a symbol with a single possible value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's spot on. I hadn't noticed that the strlen_exact
callback doesn't concretise the individual bytes but uses the solver API to check whether a byte is null
, avoiding any forks. Definitely an oversight on my part.
I will replace that test with one that creates a Manticore instance and then raises a ConcretizeException
on a constrained symbolic variable, then just checks that no additional states were created using will_fork_state_callback
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have replaced the test with another one here: https://github.com/trailofbits/manticore/blob/003ce0ad620046e9602e95c1eb2c763ba66cedf9/tests/other/test_fork.py
The new test executes the simple hello_world
program and artificially concretises a symbolic variable (constrained to one unique value) from a hook, and finally asserts that no additional states were created when forking. Let me know what you think!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new test looks great!
* master: (35 commits) Switch to stable Black (#2536) Fix typo in Manticore.linux constructor docstring (#2535) Revert CI changes made in #2526 Release Manticore 0.3.7 (#2526) Optimise forking when there is only 1 solution (#2527) Epoll Implementation (#2529) Split off ENDBR32/64 from CHESS branch (#2533) Update to crytic-compile 0.2.2 (#2530) Also ignore missing unicorn registers in the fallback emulator (#2531) x86 FXSAVE & FXRSTOR support (#2511) Fix `BitVecExtract` simplification for constant folding (#2524) Add pip-audit action workflow (#2513) Add EXPLICIT fork policy (#2514) Enforce crytic-compile==0.2.1 (#2512) Improve namedtuple definition (#2506) Add SMT simplifications for bitvec subtraction (#2504) Fix handling of the program base address in Linux (#2500) Bump Sphinx version to 4.3.0 (#2503) Solver Improvements (#2502) Improves `namedtuple` definition (#2501) ...
* master: Switch to stable Black (#2536) Fix typo in Manticore.linux constructor docstring (#2535) Revert CI changes made in #2526 Release Manticore 0.3.7 (#2526) Optimise forking when there is only 1 solution (#2527) Epoll Implementation (#2529) Split off ENDBR32/64 from CHESS branch (#2533) Update to crytic-compile 0.2.2 (#2530) Also ignore missing unicorn registers in the fallback emulator (#2531) x86 FXSAVE & FXRSTOR support (#2511) Fix `BitVecExtract` simplification for constant folding (#2524) Add pip-audit action workflow (#2513) Add EXPLICIT fork policy (#2514) Enforce crytic-compile==0.2.1 (#2512) Improve namedtuple definition (#2506) Add SMT simplifications for bitvec subtraction (#2504) Fix handling of the program base address in Linux (#2500)
This PR improves the forking process when there is only one possible solution for the symbolic expression upon which we fork. In that case, we re-use the same
State
instead of copying the entire state to create a new one.I don't think that Manticore has many tests for forks except this one:
manticore/tests/native/test_models.py
Lines 227 to 263 in 9321100
I did test this PR in CHESS, but we should add a Manticore testcase for forking on a single solution since it hits a rarer and slightly different code path than regular forking.