-
Notifications
You must be signed in to change notification settings - Fork 277
Add function pointer restriction feature #5257
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
Add function pointer restriction feature #5257
Conversation
ade1ce9
to
031dd8e
Compare
|
||
### Motivation | ||
|
||
CBMC comes with a way to resolve calls to function pointers to direct function |
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 documentation needs to be updated to reference goto-instrument
instead of cbmc
(also usage examples need to be updated to emphasise that this is a two-four step process source →binary→instrument→cbmc
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.
On the whole - I think this is a really good PR, lots of clear names, functions do what they say. It is easy to see how it all plugs together. Also a big fan of what seems to be some very robust user error handling 👍
Got a bunch of comments that basically come in two flavours:
- lots of opportunities for unit tests which would give much greater confidence on the edge cases in the code and saves 10s of regression tests!
- some large blocks of code that are quite intimidating to start reading that I think a few simple refactors could greatly improve readability
I haven't yet reviewed the regression tests or documentation, but thought I'd leave the code comments so you could begin incorporating the ones you agree with
assume_false_location, goto_programt::make_skip()); | ||
for(auto const &restriction_target : restriction.second) | ||
{ | ||
auto new_instruction = original_function_call_instruction; |
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.
💡 This definitively should be pulled out into a separate function, independently unit tested to get an idea of what goto code it produces.
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.
Put this into a separate function. I think it is not necessary to add unit tests as this functionality is very well tested by the regression tests already.
} | ||
|
||
template <typename Handler> | ||
void for_each_function_call(goto_functiont &goto_function, Handler handler) |
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'd much prefer using the range framework rather than introducing these helper functions
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 didn’t even know we had that in cbmc!
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 would prefer those functions actually. Kept them.
@@ -0,0 +1,415 @@ | |||
/*******************************************************************\ |
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.
This file is pretty big - I'd be tempted to split up the command line option parsing / error checking from the goto code transformation stuff
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.
450 lines is still within reasonable bounds IMO
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.
It is hard to see exactly what the tests are testing, I think a short sentence at the foot of each desc describing it's purpose, so appologies if there are tests for the following:
- writing to a json file (I saw the code - not sure how it is to be used in this PR)
- multiple distinct function pointer calls replaced
- a function pointer call that isn't replaced
- multiple calls to the same function pointer being replaced by different fps
- parsing a mismatched type (though think we should test all of the error checks fully through unit tests - this would just be to check the validation code is indeed being used)
\[use_fg.assertion.2\] line \d+ assertion \(choice \? fptr : gptr\)\(10\) == 10 \+ choice: SUCCESS | ||
\[use_fg.assertion.1\] line \d+ dereferenced function pointer at use_fg.function_pointer_call.1 must be one of \[(f|g), (f|g)\]: SUCCESS | ||
^EXIT=0$ | ||
^SIGNAL=0$ |
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.
🚫 Please add explanations for each test into the desc file
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.
Done
### Motivation | ||
|
||
The CPROVER framework includes a goto program transformation pass | ||
`remove_function_pointers()` to resolve calls to function pointers to direct | ||
function calls. The pass is needed by `cbmc`, as symbolic execution itself can't | ||
handle calls to function pointers. In practice, the transformation pass works as | ||
follows: |
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.
💡 this is kind of an impl detail - and as such I'd be tempted to bury it at the bottom of the docs
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.
Will leave refactoring the documentation to the next PR as it changes some things.
@@ -0,0 +1,7 @@ | |||
CORE | |||
test.c | |||
--restrict-function-pointer "use_fg.function_pointer_call.1/f,g" |
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.
❓ What is the point of function_pointer_call
, why isn't the syntax just use_fg.1/f,g
?
❓ Can I specify more all calls? e.g. use_fg/f,g
for all calls inside use_fg
?
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.
- This could be shortened, yes.
- No, but something similar is in a follow up PR
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.
Will defer 1 to the next PR.
regression/goto-instrument/restrict-function-pointer-to-complex-expression/test.c
Show resolved
Hide resolved
regression/goto-instrument/restrict-function-pointer-to-complex-expression/test.c
Outdated
Show resolved
Hide resolved
regression/goto-instrument/restrict-function-pointer-to-multiple-functions-code-check/test.desc
Show resolved
Hide resolved
.../restrict-function-pointer-to-multiple-functions-via-file-and-command-line-options/test.desc
Show resolved
Hide resolved
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.
Addressing some of Thomas’s comments.
@@ -0,0 +1,7 @@ | |||
CORE | |||
test.c | |||
--restrict-function-pointer "use_fg.function_pointer_call.1/f,g" |
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.
- This could be shortened, yes.
- No, but something similar is in a follow up PR
regression/goto-instrument/restrict-function-pointer-to-complex-expression/test.c
Outdated
Show resolved
Hide resolved
regression/goto-instrument/restrict-function-pointer-to-complex-expression/test.c
Show resolved
Hide resolved
regression/goto-instrument/restrict-function-pointer-to-multiple-functions-code-check/test.desc
Show resolved
Hide resolved
.../restrict-function-pointer-to-multiple-functions-via-file-and-command-line-options/test.desc
Show resolved
Hide resolved
} | ||
|
||
template <typename Handler> | ||
void for_each_function_call(goto_functiont &goto_function, Handler handler) |
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 didn’t even know we had that in cbmc!
Looks like there's a ton of comments to look at-- let me know when this / its successor PR are in final-ish state and waiting on code owners? |
6a36eaa
to
36ffcfd
Compare
4559d89
to
5285bb0
Compare
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.
Only skimmed the code, didn't review the docs or tests
goto_model.symbol_table.lookup_ref(goto_function.first).mode; | ||
|
||
auto const call_site_symbol_name = | ||
irep_idt{id2string(goto_function.first) + ".function_pointer_call." + |
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.
May be best not to use .
since it delimits members, and this isn't one ($ has been used elsewhere for a reserved character that doesn't mean anything in C)
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.
Agreed. This will change in the next PR anyways so I'll leave this as is for now.
|
||
for_each_function_call( | ||
goto_function, | ||
std::bind( |
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.
This is one verbose way to write
[&](const goto_programt::targett &location) { handle_call(goto_function, goto_model, restrictions, location); }
37f059e
to
2c4e416
Compare
2c4e416
to
a694533
Compare
This adds a new option, --restrict-function-pointer, to goto-instrument. This lets a user specify a list of possible pointer targets for specific function pointer call sites, rather than have remove_function_pointers guess possible values. The intended purpose behind this is to prevent excessive symex time wasted on exploring paths the user knows the program can never actually take.
Update to reflect that the feature is now a goto-instrument analysis
Codecov Report
@@ Coverage Diff @@
## develop #5257 +/- ##
===========================================
+ Coverage 67.46% 67.49% +0.03%
===========================================
Files 1164 1167 +3
Lines 95850 96045 +195
===========================================
+ Hits 64661 64827 +166
- Misses 31189 31218 +29
Continue to review full report at Codecov.
|
Replaces #5168