-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Remove more field-to-object flow #5327
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
Conversation
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.
Do we have a test case where this improves the results, or is it only to make #3364 work correctly?
@@ -178,6 +178,22 @@ private module Cached { | |||
) | |||
} | |||
|
|||
/** | |||
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`. |
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 should be "partially overlaps with", I believe. A "total" overlap overwrites all bits but could be a larger write or with a different type, an "exact" overlap writes with the same type and overwrites all bits.
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.
Good point. I've fixed this in c86fc22.
…esLocation when Alias::getEndBitOffset doesn't have known 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.
LGTM. I'll merge this to unblock further work. @dbartol, do come back with a review if you have any reservations -- there is still time to change the interface or the implementation.
I forgot to link to the CPP-differences results. Here they are in case we need to look at them again later. |
Copy/paste from my comment here:
While looking through the CPP-differences changes for #3364 I found another source of field -> object taint in
simpleInstructionLocalFlowStep
inDataFlowUtil
:This rule ensures that we get flow from the
WriteSideEffect
after callingset_value
to the argument tosink
in this example:however, it also transfers flow from the
WriteSideEffect
to thesink
argument in the following case:this pattern gave rise to some field conflation on
cpp/uncontrolled-allocation-size
on OpenJDK and oncpp/unbounded-write
on vim.The fix is to restrict the rule in
simpleInstructionLocalFlowStep
to only propagate flow from theWriteSideEffect
to theChi
when we know that theChi
isn't only a partial update.We should be able to use thegetUpdatedInterval
predicate on theChiInstruction
for this.I was right about everything except for the very last line. It's not so easy to use
getUpdatedInterval
to detect whether the entire memory location is updated since (AFAIK) it's not possible to get the type of the memory location without digging into SSA. So I added a new predicate onChiInstruction
that forwards to a new predicate inSSAConstruction.qll
which then does the actual work.Unfortunately, we lose a couple of results in dataflow. This is due to field flow not looking "deep enough" through the destination address on write side effects (i.e., we only look check whether the destination instruction is a
FieldAddress
or not, but we should traverse through the entire chain of instructions like in #5127). SosimpleInstructionLocalFlowStep
expects field flow to handle this case, but it currently doesn't.@dbartol / @rdmarsh2 I'd appreciate your thoughts on the first commit (i.e. 200d947).
(Part of https://github.com/github/codeql-c-analysis-team/issues/103.)