Compare commits

...

2 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
e94e1bb65b re-optimize without being unsound 2022-03-17 10:55:55 +01:00
Esben Sparre Andreasen
e16470a2ae undo unsound performance optimizations
For an ordinary path-problem query, it is a requirement that at least one sink exists, otherwise there is nothing to alert on.
Thus the optimization with checking `isSink(_, this, _)` pruning in `Configuration::hasFlow` is sound.

For programs without any relevant sinks (which is likely to be the case when ATM is used), the `Configuration::hasFlow` calls will not hold due to the above pruning step.
The optimizations removed in this commit are thus unsound for programs without any relevant sinks.
2022-03-16 21:49:52 +01:00
2 changed files with 30 additions and 5 deletions

View File

@@ -34,7 +34,7 @@ module ATM {
*/ */
pragma[inline] pragma[inline]
float getScoreForFlow(DataFlow::Node source, DataFlow::Node sink) { float getScoreForFlow(DataFlow::Node source, DataFlow::Node sink) {
any(DataFlow::Configuration cfg).hasFlow(source, sink) and Optimizations::hasFlow(source, sink) and
shouldResultBeIncluded(source, sink) and shouldResultBeIncluded(source, sink) and
result = unique(float s | s = any(ScoringResults results).getScoreForFlow(source, sink)) result = unique(float s | s = any(ScoringResults results).getScoreForFlow(source, sink))
} }
@@ -121,4 +121,26 @@ module ATM {
) )
} }
} }
/**
* Predicates for performance improvements that should not affect the semantics.
*/
module Optimizations {
/**
* EXPERIMENTAL. This API may change in the future.
*
* Holds if data may flow from `source` to `sink` for *some* configuration.
*
* This is a variant of `Configuration::hasFlow`, that does not require the precense of a source and a sink.
*/
predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(DataFlow::Configuration cfg |
exists(DataFlow::SourcePathNode flowsource, DataFlow::SinkPathNode flowsink |
cfg.hasFlowPath(flowsource, flowsink) and
source = flowsource.getNode() and
sink = flowsink.getNode()
)
)
}
}
} }

View File

@@ -9,6 +9,7 @@ private import BaseScoring
private import EndpointFeatures as EndpointFeatures private import EndpointFeatures as EndpointFeatures
private import FeaturizationConfig private import FeaturizationConfig
private import EndpointTypes private import EndpointTypes
private import AdaptiveThreatModeling
private string getACompatibleModelChecksum() { private string getACompatibleModelChecksum() {
availableMlModels(result, "javascript", _, "atm-endpoint-scoring") availableMlModels(result, "javascript", _, "atm-endpoint-scoring")
@@ -23,9 +24,11 @@ module ModelScoring {
RelevantFeaturizationConfig() { this = "RelevantFeaturization" } RelevantFeaturizationConfig() { this = "RelevantFeaturization" }
override DataFlow::Node getAnEndpointToFeaturize() { override DataFlow::Node getAnEndpointToFeaturize() {
getCfg().isEffectiveSource(result) and any(DataFlow::Configuration cfg).hasFlow(result, _) getCfg().isEffectiveSource(result) and
ATM::Optimizations::hasFlow(result, _)
or or
getCfg().isEffectiveSink(result) and any(DataFlow::Configuration cfg).hasFlow(_, result) getCfg().isEffectiveSink(result) and
ATM::Optimizations::hasFlow(_, result)
} }
} }
@@ -146,7 +149,7 @@ module Debugging {
query predicate endpointScores = ModelScoring::endpointScores/3; query predicate endpointScores = ModelScoring::endpointScores/3;
query predicate shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) { query predicate shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) {
any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink) and ATM::Optimizations::hasFlow(source, sink) and
any(DataFlow::Configuration cfg).hasFlow(source, sink) any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink)
} }
} }