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]
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
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 FeaturizationConfig
private import EndpointTypes
private import AdaptiveThreatModeling
private string getACompatibleModelChecksum() {
availableMlModels(result, "javascript", _, "atm-endpoint-scoring")
@@ -23,9 +24,11 @@ module ModelScoring {
RelevantFeaturizationConfig() { this = "RelevantFeaturization" }
override DataFlow::Node getAnEndpointToFeaturize() {
getCfg().isEffectiveSource(result) and any(DataFlow::Configuration cfg).hasFlow(result, _)
getCfg().isEffectiveSource(result) and
ATM::Optimizations::hasFlow(result, _)
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 shouldResultBeIncluded(DataFlow::Node source, DataFlow::Node sink) {
any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink) and
any(DataFlow::Configuration cfg).hasFlow(source, sink)
ATM::Optimizations::hasFlow(source, sink) and
any(ScoringResults scoringResults).shouldResultBeIncluded(source, sink)
}
}