-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Fix pointer/pointee conflation #13191
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
Changes from all commits
35e91ba
150d4f3
c93a051
402212b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -657,24 +657,16 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { | |
* So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the | ||
* first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`. | ||
*/ | ||
private predicate adjustForPointerArith( | ||
DefOrUse defOrUse, Node nodeFrom, UseOrPhi use, boolean uncertain | ||
) { | ||
nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and | ||
exists(Node adjusted | | ||
indirectConversionFlowStep*(adjusted, nodeFrom) and | ||
nodeToDefOrUse(adjusted, defOrUse, uncertain) and | ||
private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) { | ||
exists(DefOrUse defOrUse, Node adjusted | | ||
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and | ||
nodeToDefOrUse(adjusted, defOrUse, _) and | ||
adjacentDefRead(defOrUse, use) | ||
) | ||
} | ||
|
||
private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) { | ||
// `nodeFrom = any(PostUpdateNode pun).getPreUpdateNode()` is implied by adjustedForPointerArith. | ||
exists(UseOrPhi use | | ||
adjustForPointerArith(defOrUse, nodeFrom, use, uncertain) and | ||
useToNode(use, nodeTo) | ||
or | ||
not nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and | ||
nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and | ||
adjacentDefRead(defOrUse, use) and | ||
useToNode(use, nodeTo) and | ||
|
@@ -719,14 +711,19 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) { | |
) | ||
} | ||
|
||
private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) { | ||
arg.argumentOf(call, _) | ||
} | ||
|
||
/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */ | ||
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) { | ||
exists(Node preUpdate, Node nFrom, boolean uncertain, SsaDefOrUse defOrUse | | ||
exists(UseOrPhi use, Node preUpdate | | ||
adjustForPointerArith(pun, use) and | ||
useToNode(use, nodeTo) and | ||
preUpdate = pun.getPreUpdateNode() and | ||
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) | ||
| | ||
if uncertain = true | ||
then preUpdate = [nFrom, getAPriorDefinition(defOrUse)] | ||
else preUpdate = nFrom | ||
MathiasVP marked this conversation as resolved.
Show resolved
Hide resolved
|
||
not exists(DataFlowCall call | | ||
isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Final question from my side. I think I mostly follow along now, but would definitely appreciate @rdmarsh2's input. What is the reason for ignoring the argument positions here? Assuming this is important, could we add a test for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It shouldn't be important, no. The main thing is that we want to disallow flow from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With that said, I'd also be interested in knowing if I've missed something here (cc @rdmarsh2). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there would never be a correct step directly from the postupdate to a preupdate on the same call... That ought to only be possible in a loop, and there should be an intervening phi node in that case. If it does come up I think it's an IR inconsistency problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I agree. The closest we can come to flow directly from a int x = 0;
// ...
while(...) {
write_to_arg(&x);
} where we'd have flow from |
||
) | ||
) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,16 @@ | ||
edges | ||
| tests.cpp:26:15:26:23 | badSource indirection | tests.cpp:51:12:51:20 | call to badSource indirection | | ||
| tests.cpp:26:32:26:35 | data indirection | tests.cpp:26:15:26:23 | badSource indirection | | ||
| tests.cpp:26:32:26:35 | data indirection | tests.cpp:38:25:38:36 | strncat output argument | | ||
| tests.cpp:33:34:33:39 | call to getenv indirection | tests.cpp:38:39:38:49 | environment indirection | | ||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | badSource indirection | | ||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | badSource indirection | | ||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:51:22:51:25 | badSource output argument | | ||
| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument | | ||
| tests.cpp:51:12:51:20 | call to badSource indirection | tests.cpp:53:16:53:19 | data indirection | | ||
| tests.cpp:51:22:51:25 | badSource output argument | tests.cpp:51:22:51:25 | data indirection | | ||
| tests.cpp:51:22:51:25 | data indirection | tests.cpp:26:32:26:35 | data indirection | | ||
| tests.cpp:51:22:51:25 | data indirection | tests.cpp:51:12:51:20 | call to badSource indirection | | ||
nodes | ||
| tests.cpp:26:15:26:23 | badSource indirection | semmle.label | badSource indirection | | ||
| tests.cpp:26:15:26:23 | badSource indirection | semmle.label | badSource indirection | | ||
| tests.cpp:26:32:26:35 | data indirection | semmle.label | data indirection | | ||
| tests.cpp:33:34:33:39 | call to getenv indirection | semmle.label | call to getenv indirection | | ||
| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument | | ||
| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument | | ||
| tests.cpp:38:39:38:49 | environment indirection | semmle.label | environment indirection | | ||
| tests.cpp:51:12:51:20 | call to badSource indirection | semmle.label | call to badSource indirection | | ||
| tests.cpp:51:22:51:25 | badSource output argument | semmle.label | badSource output argument | | ||
| tests.cpp:51:22:51:25 | data indirection | semmle.label | data indirection | | ||
| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection | | ||
subpaths | ||
| tests.cpp:51:22:51:25 | data indirection | tests.cpp:26:32:26:35 | data indirection | tests.cpp:26:15:26:23 | badSource indirection | tests.cpp:51:12:51:20 | call to badSource indirection | | ||
#select | ||
| tests.cpp:53:16:53:19 | data | tests.cpp:33:34:33:39 | call to getenv indirection | tests.cpp:53:16:53:19 | data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | tests.cpp:33:34:33:39 | call to getenv indirection | user input (an environment variable) | tests.cpp:38:25:38:36 | strncat output argument | strncat output argument | |
Check warning
Code scanning / CodeQL
Missing QLDoc for parameter