-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Shared: Generate more value-preserving flow summaries #19443
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 1 commit
607a1e4
cd47379
07641e4
7751973
d8eafbb
d5bc95d
54f0eed
4d2f2b8
37bc2bf
bce5f25
6437168
6c9f248
a94cffa
09dc3c8
ee83ca9
6712cce
fcecc5a
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 |
---|---|---|
|
@@ -345,12 +345,14 @@ module MakeModelGeneratorFactory< | |
/** | ||
* Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`). | ||
*/ | ||
private string captureQualifierFlow(DataFlowSummaryTargetApi api) { | ||
private string captureQualifierFlow(DataFlowSummaryTargetApi api, string input, string output) { | ||
exists(ReturnNodeExt ret | | ||
api = returnNodeEnclosingCallable(ret) and | ||
isOwnInstanceAccessNode(ret) | ||
) and | ||
result = ModelPrintingSummary::asLiftedValueModel(api, qualifierString(), "ReturnValue") | ||
input = qualifierString() and | ||
output = "ReturnValue" and | ||
result = ModelPrintingSummary::asLiftedValueModel(api, input, output) | ||
} | ||
|
||
private int accessPathLimit0() { result = 2 } | ||
|
@@ -430,7 +432,7 @@ module MakeModelGeneratorFactory< | |
predicate isSink(DataFlow::Node sink) { | ||
sink instanceof ReturnNodeExt and | ||
not isOwnInstanceAccessNode(sink) and | ||
not exists(captureQualifierFlow(getAsExprEnclosingCallable(sink))) | ||
not exists(captureQualifierFlow(getAsExprEnclosingCallable(sink), _, _)) | ||
} | ||
|
||
predicate isAdditionalFlowStep = PropagateFlowConfigInput::isAdditionalFlowStep/4; | ||
|
@@ -559,11 +561,24 @@ module MakeModelGeneratorFactory< | |
* | ||
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. | ||
*/ | ||
private string captureThroughFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { | ||
exists(string input, string output | | ||
preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and | ||
result = ModelPrintingSummary::asLiftedModel(api, input, output, preservesValue) | ||
) | ||
private string captureThroughFlow( | ||
DataFlowSummaryTargetApi api, string input, string output, boolean preservesValue | ||
) { | ||
preservesValue = max(boolean b | captureThroughFlow0(api, _, input, _, output, b)) and | ||
result = ModelPrintingSummary::asLiftedModel(api, input, output, preservesValue) | ||
} | ||
|
||
/** | ||
* Gets the summary model(s) of `api`, if there is flow `input` to | ||
* `output`. `preservesValue` is `true` if the summary is value- | ||
* preserving, and `false` otherwise. | ||
*/ | ||
string captureFlow( | ||
DataFlowSummaryTargetApi api, string input, string output, boolean preservesValue | ||
) { | ||
result = captureQualifierFlow(api, input, output) and preservesValue = true | ||
or | ||
result = captureThroughFlow(api, input, output, preservesValue) | ||
} | ||
|
||
/** | ||
|
@@ -573,9 +588,7 @@ module MakeModelGeneratorFactory< | |
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. | ||
*/ | ||
string captureFlow(DataFlowSummaryTargetApi api, boolean preservesValue) { | ||
result = captureQualifierFlow(api) and preservesValue = true | ||
or | ||
result = captureThroughFlow(api, preservesValue) | ||
result = captureFlow(api, _, _, preservesValue) | ||
} | ||
|
||
/** | ||
|
@@ -947,19 +960,20 @@ module MakeModelGeneratorFactory< | |
} | ||
|
||
/** | ||
* Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to | ||
* the return value or a parameter). `lift` is true, if the model should be lifted, otherwise false. | ||
* Gets the content based summary model(s) of the API `api` (if there is flow from `input` to | ||
* `output`). `lift` is true, if the model should be lifted, otherwise false. | ||
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise. | ||
* | ||
* Models are lifted to the best type in case the read and store access paths do not | ||
* contain a field or synthetic field access. | ||
*/ | ||
string captureFlow(ContentDataFlowSummaryTargetApi api, boolean lift, boolean preservesValue) { | ||
exists(string input, string output | | ||
captureFlow0(api, input, output, _, lift) and | ||
preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and | ||
result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift) | ||
) | ||
string captureFlow( | ||
ContentDataFlowSummaryTargetApi api, string input, string output, boolean lift, | ||
boolean preservesValue | ||
) { | ||
captureFlow0(api, input, output, _, lift) and | ||
preservesValue = max(boolean p | captureFlow0(api, input, output, p, lift)) and | ||
result = ContentModelPrinting::asModel(api, input, output, preservesValue, lift) | ||
} | ||
} | ||
|
||
|
@@ -972,23 +986,30 @@ module MakeModelGeneratorFactory< | |
* generate flow summaries using the heuristic based summary generator. | ||
*/ | ||
string captureFlow(DataFlowSummaryTargetApi api, boolean lift) { | ||
exists(boolean preservesValue | | ||
result = ContentSensitive::captureFlow(api, lift, preservesValue) | ||
or | ||
not exists(DataFlowSummaryTargetApi api0 | | ||
// If the heuristic summary is value-preserving then we keep both | ||
// summaries. However, if we can generate any content-sensitive | ||
// summary (value-preserving or not) then we don't include any taint- | ||
// based heuristic summary. | ||
preservesValue = false | ||
result = ContentSensitive::captureFlow(api, _, _, lift, _) | ||
or | ||
exists(boolean preservesValue, string input, string output | | ||
not exists( | ||
DataFlowSummaryTargetApi api0, string input0, string output0, boolean preservesValue0 | ||
| | ||
// If the heuristic summary is taint-based, and we can generate a content-sensitive | ||
// summary that is value-preserving then we omit generating any heuristic summary. | ||
preservesValue = false and | ||
preservesValue0 = true | ||
or | ||
// However, if they're both value-preserving (or both taint-based) then we only | ||
// generate a heuristic summary if we didn't generate a content-sensitive summary. | ||
preservesValue = preservesValue0 and | ||
input0 = input and | ||
output0 = output | ||
| | ||
(api0 = api or api.lift() = api0) and | ||
exists(ContentSensitive::captureFlow(api0, false, _)) | ||
exists(ContentSensitive::captureFlow(api0, input0, output0, false, preservesValue0)) | ||
or | ||
api0.lift() = api.lift() and | ||
exists(ContentSensitive::captureFlow(api0, true, _)) | ||
exists(ContentSensitive::captureFlow(api0, input0, output0, true, preservesValue0)) | ||
) and | ||
result = Heuristic::captureFlow(api, preservesValue) and | ||
result = Heuristic::captureFlow(api, input, output, preservesValue) and | ||
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. This change does a bit more than de-duplicating the generated summaries. 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. Oh, that's a good point. I think the behavior you want is what we get if we get rid of this disjunct: // If the heuristic summary is taint-based, and we can generate a content-sensitive
// summary that is value-preserving then we omit generating any heuristic summary.
preservesValue = false and
preservesValue0 = true right? Then we'd only generate a heuristic summary if we fail to generate a content-sensitive with exactly the same I'm happy to do that if you'd rather want this behavior? 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 realised that my previous comment is not entirely correct.
That is, we only exclude a summary 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. Oh! Hm, yeah I can see how that's a problem. Should we delay deduplication until we see whether it's actually a problem in practice? I'd really like to somehow get this working as the taint summaries we get for OpenSSL isn't sufficient for what we need them for 😭 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 tried re-generating the .NET runtime models - and we do get some models that we don't want.
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. Thanks a lot for regenerating the .NET runtime models 🙇 Yeah, feel free to experiment on the PR all you want. Let me know if I can do something to help out! 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 should also add: I think the filtering you propose there makes a lot of sense, and I also just checked that it still gives us the models we care about 🥳 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. Great! 😄
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. That's fantastic, Michael! I've pushed your commits now 🙇 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. Excellent - and thank you very much for contributing to the model generator @MathiasVP - I really appreciate it! |
||
lift = true | ||
) | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.