From facda77852aabce63721cb66f8b16ff0941cb647 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 9 Dec 2021 16:56:38 +0000 Subject: [PATCH] Dataflow relations: narrow all dataflow nodes before taking product with Configurations This is particularly important for ConversionWithoutBoundsCheckConfig which has 20 configs. By paring DataFlow::Node down to only those that have a local-flow successor, or only those with an isAdditionalFlowStep for some related configuration, the result size can be significantly reduced prior to taking the product against Configuration and finally paring down using config.fullBarrier etc. Saves about 1m20s per analysis on cockroachdb. --- .../go/dataflow/internal/DataFlowImpl.qll | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 42d7e89f20b..f535bef3231 100644 --- a/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -332,7 +332,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -351,7 +351,8 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + pragma[only_bind_into](config) + .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -371,7 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -384,7 +385,8 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + pragma[only_bind_into](config) + .isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -392,8 +394,12 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c } private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) { - read(node1.asNode(), c, node2.asNode()) and - stepFilter(node1, node2, config) + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + read(pragma[only_bind_into](n1), c, pragma[only_bind_into](n2)) and + stepFilter(node1, node2, config) + ) or exists(Node n | node2.isImplicitReadNode(n, true) and @@ -405,9 +411,13 @@ private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration conf private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and - read(_, tc.getContent(), _, config) and - stepFilter(node1, node2, config) + exists(Node n1, Node n2 | + node1.asNode() = n1 and + node2.asNode() = n2 and + store(pragma[only_bind_into](n1), tc, pragma[only_bind_into](n2), contentType) and + read(_, tc.getContent(), _, config) and + stepFilter(node1, node2, config) + ) } pragma[nomagic]