From c80627a3d36d030e003e75a8fb807fb3bd42b147 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 19 Sep 2024 10:31:09 +0200 Subject: [PATCH 01/15] Dataflow: add plumbing for adding provenance to state-steps. --- .../cpp/dataflow/internal/DataFlowImpl1.qll | 10 ++- .../cpp/dataflow/internal/DataFlowImpl2.qll | 10 ++- .../cpp/dataflow/internal/DataFlowImpl3.qll | 10 ++- .../cpp/dataflow/internal/DataFlowImpl4.qll | 10 ++- .../dataflow/internal/DataFlowImplLocal.qll | 10 ++- .../ir/dataflow/internal/DataFlowImpl1.qll | 10 ++- .../ir/dataflow/internal/DataFlowImpl2.qll | 10 ++- .../ir/dataflow/internal/DataFlowImpl3.qll | 10 ++- .../ir/dataflow/internal/DataFlowImpl4.qll | 10 ++- .../dataflow/internal/DataFlowImpl1.qll | 10 ++- .../dataflow/internal/DataFlowImpl2.qll | 10 ++- .../dataflow/internal/DataFlowImpl3.qll | 10 ++- .../dataflow/internal/DataFlowImpl4.qll | 10 ++- .../dataflow/internal/DataFlowImpl5.qll | 10 ++- .../go/dataflow/internal/DataFlowImpl1.qll | 10 ++- .../go/dataflow/internal/DataFlowImpl2.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl1.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl2.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl3.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl4.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl5.qll | 10 ++- .../java/dataflow/internal/DataFlowImpl6.qll | 10 ++- .../dataflow/new/internal/DataFlowImpl1.qll | 10 ++- .../dataflow/new/internal/DataFlowImpl2.qll | 10 ++- .../dataflow/new/internal/DataFlowImpl3.qll | 10 ++- .../dataflow/new/internal/DataFlowImpl4.qll | 10 ++- .../ruby/dataflow/internal/DataFlowImpl1.qll | 10 ++- .../ruby/dataflow/internal/DataFlowImpl2.qll | 10 ++- shared/dataflow/codeql/dataflow/DataFlow.qll | 6 ++ .../codeql/dataflow/TaintTracking.qll | 9 ++- .../codeql/dataflow/internal/DataFlowImpl.qll | 72 ++++++++++--------- .../swift/dataflow/internal/DataFlowImpl1.qll | 10 ++- 32 files changed, 256 insertions(+), 121 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index ce964917e970..17def0c431db 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index ce964917e970..17def0c431db 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index ce964917e970..17def0c431db 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index ce964917e970..17def0c431db 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index ce964917e970..17def0c431db 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index ce964917e970..17def0c431db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index ce964917e970..17def0c431db 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index ce964917e970..17def0c431db 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 01bd0e5ea963..7a2f78089778 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -676,6 +676,12 @@ module DataFlowMake Lang> { predicate isAdditionalFlowStep(Node node1, Node node2, string model) { Config::isAdditionalFlowStep(node1, node2) and model = "Config" } + + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { + Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config" + } } import Impl diff --git a/shared/dataflow/codeql/dataflow/TaintTracking.qll b/shared/dataflow/codeql/dataflow/TaintTracking.qll index 343f8be041f5..a769b8580288 100644 --- a/shared/dataflow/codeql/dataflow/TaintTracking.qll +++ b/shared/dataflow/codeql/dataflow/TaintTracking.qll @@ -63,7 +63,7 @@ module TaintFlowMake< Config::isSink(node) or Config::isSink(node, _) or Config::isAdditionalFlowStep(node, _, _) or - Config::isAdditionalFlowStep(node, _, _, _) + Config::isAdditionalFlowStep(node, _, _, _, _) ) and defaultImplicitTaintRead(node, c) } @@ -108,6 +108,13 @@ module TaintFlowMake< ) { Config::isAdditionalFlowStep(node1, node2) and model = "Config" } + + predicate isAdditionalFlowStep( + DataFlowLang::Node node1, FlowState state1, DataFlowLang::Node node2, FlowState state2, + string model + ) { + Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config" + } } private module C implements DataFlowInternal::FullStateConfigSig { diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 1bebea93c486..5d8d8bd293ca 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -73,7 +73,9 @@ module MakeImpl Lang> { * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. * This step is only applicable in `state1` and updates the flow state to `state2`. */ - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2); + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ); /** * Holds if an arbitrary number of implicit read steps of content `c` may be @@ -153,7 +155,9 @@ module MakeImpl Lang> { predicate isBarrierOut(Node node, FlowState state) { none() } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { none() } } @@ -357,12 +361,13 @@ module MakeImpl Lang> { } private predicate additionalLocalStateStep( - NodeEx node1, FlowState s1, NodeEx node2, FlowState s2 + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, string model ) { exists(Node n1, Node n2 | node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and - Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2, + model) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stateStepFilter(node1, s1, node2, s2) ) @@ -395,11 +400,14 @@ module MakeImpl Lang> { ) } - private predicate additionalJumpStateStep(NodeEx node1, FlowState s1, NodeEx node2, FlowState s2) { + private predicate additionalJumpStateStep( + NodeEx node1, FlowState s1, NodeEx node2, FlowState s2, string model + ) { exists(Node n1, Node n2 | node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and - Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and + Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2, + model) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stateStepFilter(node1, s1, node2, s2) and not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -530,13 +538,13 @@ module MakeImpl Lang> { exists(NodeEx mid | fwdFlow(mid, cc) | localFlowStepEx(mid, node, _) or additionalLocalFlowStep(mid, node, _) or - additionalLocalStateStep(mid, _, node, _) + additionalLocalStateStep(mid, _, node, _, _) ) or exists(NodeEx mid | fwdFlow(mid, _) and cc = false | jumpStepEx(mid, node) or additionalJumpStep(mid, node, _) or - additionalJumpStateStep(mid, _, node, _) + additionalJumpStateStep(mid, _, node, _, _) ) or // store @@ -677,8 +685,8 @@ module MakeImpl Lang> { private predicate stateStepFwd(FlowState state1, FlowState state2) { exists(NodeEx node1 | - additionalLocalStateStep(node1, state1, _, state2) or - additionalJumpStateStep(node1, state1, _, state2) + additionalLocalStateStep(node1, state1, _, state2, _) or + additionalJumpStateStep(node1, state1, _, state2, _) | fwdFlow(node1) ) @@ -723,13 +731,13 @@ module MakeImpl Lang> { exists(NodeEx mid | revFlow(mid, toReturn) | localFlowStepEx(node, mid, _) or additionalLocalFlowStep(node, mid, _) or - additionalLocalStateStep(node, _, mid, _) + additionalLocalStateStep(node, _, mid, _, _) ) or exists(NodeEx mid | revFlow(mid, _) and toReturn = false | jumpStepEx(node, mid) or additionalJumpStep(node, mid, _) or - additionalJumpStateStep(node, _, mid, _) + additionalJumpStateStep(node, _, mid, _, _) ) or // store @@ -847,8 +855,8 @@ module MakeImpl Lang> { private predicate stateStepRev(FlowState state1, FlowState state2) { exists(NodeEx node1, NodeEx node2 | - additionalLocalStateStep(node1, state1, node2, state2) or - additionalJumpStateStep(node1, state1, node2, state2) + additionalLocalStateStep(node1, state1, node2, state2, _) or + additionalJumpStateStep(node1, state1, node2, state2, _) | revFlow(node1, _) and revFlow(node2, _) and @@ -1068,8 +1076,7 @@ module MakeImpl Lang> { ) { Stage1::revFlow(node1) and Stage1::revFlow(node2) and - additionalLocalStateStep(node1, state1, node2, state2) and - label = "Config" and + additionalLocalStateStep(node1, state1, node2, state2, label) and t = node2.getDataFlowType() and lcc.relevantFor(node1.getEnclosingCallable()) and not isUnreachableInCall1(node1, lcc) and @@ -1621,7 +1628,7 @@ module MakeImpl Lang> { or exists(NodeEx mid, FlowState state0 | fwdFlow(mid, state0, _, _, _, ap, apa) and - additionalJumpStateStep(mid, state0, node, state) and + additionalJumpStateStep(mid, state0, node, state, _) and t = getNodeTyp(node) and ap instanceof ApNil ) @@ -2286,7 +2293,7 @@ module MakeImpl Lang> { ) or exists(NodeEx mid, FlowState state0 | - additionalJumpStateStep(node, state, mid, state0) and + additionalJumpStateStep(node, state, mid, state0, _) and revFlow(pragma[only_bind_into](mid), pragma[only_bind_into](state0), _, _, ap) and ap instanceof ApNil ) @@ -2651,7 +2658,7 @@ module MakeImpl Lang> { or additionalJumpStep(_, node, _) or - additionalJumpStateStep(_, _, node, state) + additionalJumpStateStep(_, _, node, state, _) or node instanceof ParamNodeEx or @@ -2699,9 +2706,9 @@ module MakeImpl Lang> { exists(NodeEx next, FlowState s | revFlow(next, s, pragma[only_bind_into](ap)) and ap instanceof ApNil | - additionalJumpStateStep(node, state, next, s) + additionalJumpStateStep(node, state, next, s, _) or - additionalLocalStateStep(node, state, next, s) and + additionalLocalStateStep(node, state, next, s, _) and s != state ) or @@ -3246,10 +3253,9 @@ module MakeImpl Lang> { t = getNodeTyp(node) and ap instanceof ApNil or - additionalJumpStateStep(mid, state0, node, state) and + additionalJumpStateStep(mid, state0, node, state, label) and t = getNodeTyp(node) and - ap instanceof ApNil and - label = "Config" + ap instanceof ApNil ) or // flow into a callable @@ -4799,7 +4805,7 @@ module MakeImpl Lang> { or additionalJumpStep(node1, node2, _) or - additionalJumpStateStep(node1, _, node2, _) + additionalJumpStateStep(node1, _, node2, _, _) or // flow into callable viableParamArgEx(_, node2, node1) @@ -4913,10 +4919,10 @@ module MakeImpl Lang> { private predicate relevantState(FlowState state) { sourceNode(_, state) or sinkNodeWithState(_, state) or - additionalLocalStateStep(_, state, _, _) or - additionalLocalStateStep(_, _, _, state) or - additionalJumpStateStep(_, state, _, _) or - additionalJumpStateStep(_, _, _, state) + additionalLocalStateStep(_, state, _, _, _) or + additionalLocalStateStep(_, _, _, state, _) or + additionalJumpStateStep(_, state, _, _, _) or + additionalJumpStateStep(_, _, _, state, _) } private predicate revSinkNode(NodeEx node, FlowState state) { @@ -5252,7 +5258,7 @@ module MakeImpl Lang> { t = node.getDataFlowType() and ap = TPartialNil() or - additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state) and + additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, _) and cc = mid.getCallContext() and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and @@ -5287,7 +5293,7 @@ module MakeImpl Lang> { ap = TPartialNil() and isStoreStep = false or - additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state) and + additionalJumpStateStep(mid.getNodeEx(), mid.getState(), node, state, _) and cc = callContextNone() and sc1 = TSummaryCtx1None() and sc2 = TSummaryCtx2None() and @@ -5559,7 +5565,7 @@ module MakeImpl Lang> { ap = TPartialNil() and isStoreStep = false or - additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState()) and + additionalLocalStateStep(node, state, mid.getNodeEx(), mid.getState(), _) and sc1 = mid.getSummaryCtx1() and sc2 = mid.getSummaryCtx2() and sc3 = mid.getSummaryCtx3() and @@ -5584,7 +5590,7 @@ module MakeImpl Lang> { ap = TPartialNil() and isStoreStep = false or - additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState()) and + additionalJumpStateStep(node, state, mid.getNodeEx(), mid.getState(), _) and sc1 = TRevSummaryCtx1None() and sc2 = TRevSummaryCtx2None() and sc3 = TRevSummaryCtx3None() and diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll index ce964917e970..17def0c431db 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll @@ -261,13 +261,17 @@ deprecated private module Config implements FullStateConfigSig { model = "" } - predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + predicate isAdditionalFlowStep( + Node node1, FlowState state1, Node node2, FlowState state2, string model + ) { getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and - getConfig(state2) = getConfig(state1) + getConfig(state2) = getConfig(state1) and + model = "" or not singleConfiguration() and getConfig(state1).isAdditionalFlowStep(node1, node2) and - state2 = state1 + state2 = state1 and + model = "" } predicate allowImplicitRead(Node node, ContentSet c) { From 7d123296f83334638e0542b985c084cd3a46c3d9 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 19 Sep 2024 10:32:46 +0200 Subject: [PATCH 02/15] Dataflow: Add speculative flow modules. --- .../codeql/dataflow/TaintTracking.qll | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/TaintTracking.qll b/shared/dataflow/codeql/dataflow/TaintTracking.qll index a769b8580288..beec8f384993 100644 --- a/shared/dataflow/codeql/dataflow/TaintTracking.qll +++ b/shared/dataflow/codeql/dataflow/TaintTracking.qll @@ -29,6 +29,12 @@ signature module InputSig Lang> { */ bindingset[node] predicate defaultImplicitTaintRead(Lang::Node node, Lang::ContentSet c); + + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ + predicate speculativeTaintStep(Lang::Node src, Lang::Node sink); } /** @@ -130,4 +136,124 @@ module TaintFlowMake< { import GlobalWithState } + + signature int speculationLimitSig(); + + private module AddSpeculativeTaintSteps< + DataFlowInternal::FullStateConfigSig Config, speculationLimitSig/0 speculationLimit> implements + DataFlowInternal::FullStateConfigSig + { + import Config + + private predicate relevantState(Config::FlowState state) { + Config::isSource(_, state) + or + exists(Config::FlowState state0 | + relevantState(state0) and Config::isAdditionalFlowStep(_, state0, _, state, _) + ) + } + + private newtype TFlowState = + TMkFlowState(Config::FlowState state, int spec) { + relevantState(state) and spec = [0 .. speculationLimit()] + } + + class FlowState extends TFlowState { + private Config::FlowState state; + private int spec; + + FlowState() { this = TMkFlowState(state, spec) } + + string toString() { result = "FlowState" } + + Config::FlowState getState() { result = state } + + int getSpec() { result = spec } + } + + predicate isSource(DataFlowLang::Node source, FlowState state) { + Config::isSource(source, state.getState()) and state.getSpec() = 0 + } + + predicate isSink(DataFlowLang::Node sink, FlowState state) { + Config::isSink(sink, state.getState()) + } + + predicate isBarrier(DataFlowLang::Node node, FlowState state) { + Config::isBarrier(node, state.getState()) + } + + predicate isBarrierIn(DataFlowLang::Node node, FlowState state) { + Config::isBarrierIn(node, state.getState()) + } + + predicate isBarrierOut(DataFlowLang::Node node, FlowState state) { + Config::isBarrierOut(node, state.getState()) + } + + predicate isAdditionalFlowStep( + DataFlowLang::Node node1, FlowState state1, DataFlowLang::Node node2, FlowState state2, + string model + ) { + Config::isAdditionalFlowStep(node1, state1.getState(), node2, state2.getState(), model) and + state1.getSpec() = state2.getSpec() + or + speculativeTaintStep(node1, node2) and + not defaultAdditionalTaintStep(node1, node2, _) and + not Config::isAdditionalFlowStep(node1, _, node2, _, _) and + not Config::isAdditionalFlowStep(node1, node2, _) and + model = "Speculative" and + state1.getSpec() + 1 = state2.getSpec() and + state1.getState() = state2.getState() + } + } + + module SpeculativeFlow + implements DataFlow::GlobalFlowSig + { + private module Config0 implements DataFlowInternal::FullStateConfigSig { + import DataFlowInternal::DefaultState + import Config + + predicate isAdditionalFlowStep( + DataFlowLang::Node node1, DataFlowLang::Node node2, string model + ) { + Config::isAdditionalFlowStep(node1, node2) and model = "Config" + } + } + + private module C implements DataFlowInternal::FullStateConfigSig { + import AddTaintDefaults> + } + + import DataFlowInternal::Impl + } + + module SpeculativeFlowWithState< + DataFlow::StateConfigSig Config, speculationLimitSig/0 speculationLimit> implements + DataFlow::GlobalFlowSig + { + private module Config0 implements DataFlowInternal::FullStateConfigSig { + import Config + + predicate isAdditionalFlowStep( + DataFlowLang::Node node1, DataFlowLang::Node node2, string model + ) { + Config::isAdditionalFlowStep(node1, node2) and model = "Config" + } + + predicate isAdditionalFlowStep( + DataFlowLang::Node node1, FlowState state1, DataFlowLang::Node node2, FlowState state2, + string model + ) { + Config::isAdditionalFlowStep(node1, state1, node2, state2) and model = "Config" + } + } + + private module C implements DataFlowInternal::FullStateConfigSig { + import AddTaintDefaults> + } + + import DataFlowInternal::Impl + } } From 8b99154a006ce380b6a5ef03bde7fdc2a751b18d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 24 Sep 2024 13:48:41 +0200 Subject: [PATCH 03/15] Java: Add support for speculative taint flow. --- .../dataflow/internal/TaintTrackingUtil.qll | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 4984b8b050fd..a3231b4b1cf8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -658,3 +658,49 @@ private predicate entrypointFieldStep(DataFlow::Node src, DataFlow::Node sink) { ) and src.getType().(RefType).getSourceDeclaration() = entrypointType() } + +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import semmle.code.java.dataflow.ExternalFlow as ExternalFlow + private import semmle.code.java.dataflow.internal.DataFlowNodes + private import semmle.code.java.dataflow.internal.FlowSummaryImpl as Impl + private import semmle.code.java.dispatch.VirtualDispatch + private import semmle.code.java.security.Sanitizers + + private predicate hasTarget(Call call) { + exists(Impl::Public::SummarizedCallable sc | sc.getACall() = call) + or + exists(Impl::Public::NeutralSummaryCallable nc | nc.getACall() = call) + or + call.getCallee().getSourceDeclaration() instanceof ExternalFlow::SinkCallable + or + exists(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.getACall() = call) + or + exists(viableCallable(call)) + or + call.getQualifier().getType() instanceof Array + or + call.getCallee().getSourceDeclaration() instanceof CloneMethod + or + call.getCallee() + .getSourceDeclaration() + .getDeclaringType() + .getPackage() + .hasName("java.util.function") + } + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowCall call, Call srcCall, int argpos | + not hasTarget(srcCall) and + call.asCall() = srcCall and + src.(ArgumentNode).argumentOf(call, argpos) and + not src instanceof SimpleTypeSanitizer + | + argpos != -1 and + sink.(DataFlow::PostUpdateNode).getPreUpdateNode() = Public::getInstanceArgument(srcCall) + or + sink.(OutNode).getCall() = call + ) + } +} From 6c6b6061bc52f8c5198078b285a052f995e5454f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 3 Oct 2024 11:45:41 +0200 Subject: [PATCH 04/15] Dataflow: Add consistency check. --- .../dataflow/internal/DataFlowImplConsistency.qll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll index 48c4d42daaad..ca523e179c47 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll @@ -323,4 +323,18 @@ module MakeConsistency< lambdaCall(call, _, receiver) and not nodeGetEnclosingCallable(receiver) = call.getEnclosingCallable() } + + query predicate speculativeStepAlreadyHasModel(Node n1, Node n2, string model) { + speculativeTaintStep(n1, n2) and + not defaultAdditionalTaintStep(n1, n2, _) and + ( + simpleLocalFlowStep(n1, n2, _) and model = "SimpleLocalFlowStep" + or + exists(DataFlowCall call | + exists(viableCallable(call)) and + isArgumentNode(n1, call, _) and + model = "dispatch" + ) + ) + } } From 7b43100af535436f2df88ed71b58dc66366d5390 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 3 Oct 2024 11:46:31 +0200 Subject: [PATCH 05/15] C#: Add support for speculative taint flow. --- .../internal/TaintTrackingPrivate.qll | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index 25de2681862c..c5bf4b082497 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -169,3 +169,39 @@ private module Cached { } import Cached +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow + private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as Impl + + private predicate hasTarget(Call call) { + exists(Impl::Public::SummarizedCallable sc | sc.getACall() = call) + or + exists(Impl::Public::NeutralSummaryCallable nc | nc.getACall() = call) + or + call.getTarget().getUnboundDeclaration() instanceof ExternalFlow::SinkCallable + or + exists(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.getACall() = call) + } + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowCall call, Call srcCall, ArgumentPosition argpos | + not exists(viableCallable(call)) and + not hasTarget(srcCall) and + call.(NonDelegateDataFlowCall).getDispatchCall().getCall() = srcCall and + (srcCall instanceof ConstructorInitializer or srcCall instanceof MethodCall) and + src.(ArgumentNode).argumentOf(call, argpos) and + not src instanceof PostUpdateNodes::ObjectInitializerNode and + not src instanceof MallocNode + | + not argpos.isQualifier() and + sink.(PostUpdateNode) + .getPreUpdateNode() + .(ArgumentNode) + .argumentOf(call, any(ArgumentPosition qualpos | qualpos.isQualifier())) + or + sink.(OutNode).getCall(_) = call + ) + } +} From 8eb0cb4c66816b3c188d348ed92e7c093f102eda Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 3 Oct 2024 15:16:05 +0200 Subject: [PATCH 06/15] Ruby: Add tentative support for speculative taint flow. --- .../internal/TaintTrackingPrivate.qll | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index 565fea34dbc0..3c86cccd9628 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -149,3 +149,29 @@ private module Cached { } import Cached +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch + private import codeql.ruby.dataflow.internal.DataFlowPublic as DataFlowPublic + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists( + DataFlowDispatch::DataFlowCall call, MethodCall srcCall, + DataFlowDispatch::ArgumentPosition argpos + | + // TODO: exclude neutrals and anything that has QL modeling. + not exists(DataFlowDispatch::viableCallable(call)) and + call.asCall().getExpr() = srcCall and + src.(ArgumentNode).argumentOf(call, argpos) + | + not argpos.isSelf() and + sink.(DataFlowPublic::PostUpdateNode) + .getPreUpdateNode() + .(ArgumentNode) + .argumentOf(call, any(DataFlowDispatch::ArgumentPosition qualpos | qualpos.isSelf())) + or + sink.(OutNode).getCall(_) = call + ) + } +} From 7497d9530d4157fd8de88e75de66fec9b6aa4285 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 3 Oct 2024 15:35:01 +0200 Subject: [PATCH 07/15] Python: Add tentative support for speculative taint flow. --- .../new/internal/TaintTrackingPrivate.qll | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index fb46f7d6892a..8c94a4749f76 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -219,3 +219,27 @@ predicate asyncWithStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { contextManager.strictlyDominates(var) ) } + +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowDispatch + private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | + // TODO: exclude neutrals and anything that has QL modeling. + not exists(DataFlowDispatch::viableCallable(call)) and + call instanceof DataFlowDispatch::PotentialLibraryCall and + src.(DataFlowPublic::ArgumentNode).argumentOf(call, argpos) + | + not argpos.isSelf() and + sink.(DataFlowPublic::PostUpdateNode) + .getPreUpdateNode() + .(DataFlowPublic::ArgumentNode) + .argumentOf(call, any(DataFlowDispatch::ArgumentPosition qualpos | qualpos.isSelf())) + or + sink.(DataFlowDispatch::OutNode).getCall(_) = call + ) + } +} From 635071fe8a07f12c446dabe2260d370808ac6dfa Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 4 Oct 2024 10:41:04 +0200 Subject: [PATCH 08/15] Swift: Add tentative support for speculative taint flow. --- .../internal/TaintTrackingPrivate.qll | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index a6acdbc25ede..53c828981ffe 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -99,3 +99,29 @@ private module Cached { } import Cached +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import codeql.swift.dataflow.internal.DataFlowDispatch as DataFlowDispatch + private import codeql.swift.dataflow.internal.DataFlowPublic as DataFlowPublic + private import codeql.swift.dataflow.internal.DataFlowPrivate as DataFlowPrivate + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | + // TODO: exclude neutrals and anything that has QL modeling. + not exists(DataFlowDispatch::viableCallable(call)) and + src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos) + | + not argpos instanceof DataFlowDispatch::ThisArgumentPosition and + sink.(DataFlowPublic::PostUpdateNode) + .getPreUpdateNode() + .(DataFlowPrivate::ArgumentNode) + .argumentOf(call, + any(DataFlowDispatch::ArgumentPosition qualpos | + qualpos instanceof DataFlowDispatch::ThisArgumentPosition + )) + or + sink.(DataFlowPrivate::OutNode).getCall(_) = call + ) + } +} From fae71756eba82829324a05489b049a9cf4d224a3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 4 Oct 2024 10:54:10 +0200 Subject: [PATCH 09/15] Go: Add tentative support for speculative taint flow. --- .../dataflow/internal/TaintTrackingUtil.qll | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 85f6bb0874f5..0ea9dbae200a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -428,3 +428,25 @@ private class ClearSanitizer extends DefaultTaintSanitizer { ) } } + +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import semmle.go.dataflow.internal.DataFlowDispatch as DataFlowDispatch + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowPrivate::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | + // TODO: exclude neutrals and anything that has QL modeling. + not exists(DataFlowDispatch::viableCallable(call)) and + src.(DataFlow::ArgumentNode).argumentOf(call, argpos) + | + argpos != -1 and + sink.(DataFlow::PostUpdateNode) + .getPreUpdateNode() + .(DataFlow::ArgumentNode) + .argumentOf(call, -1) + or + sink.(DataFlowPrivate::OutNode).getCall() = call + ) + } +} From 4e8a4a5cddf655c2f84c1e6847f17c91920e2b6e Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 4 Oct 2024 11:21:48 +0200 Subject: [PATCH 10/15] C/C++: Add tentative support for speculative taint flow. --- .../dataflow/internal/TaintTrackingUtil.qll | 2 ++ .../dataflow/internal/TaintTrackingUtil.qll | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index 3075d3974575..0b35e74db8c4 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -281,3 +281,5 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) { } private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction } + +predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index e570ecb05423..9921be8a147d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -212,3 +212,26 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut, string nodeOut = callOutput(call, modelOut) ) } + +import SpeculativeTaintFlow + +private module SpeculativeTaintFlow { + private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as DataFlowDispatch + private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate + + predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { + exists(DataFlowCall call, ArgumentPosition argpos | + // TODO: exclude neutrals and anything that has QL modeling. + not exists(DataFlowDispatch::viableCallable(call)) and + src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos) + | + not argpos.(DirectPosition).getIndex() = -1 and + sink.(PostUpdateNode) + .getPreUpdateNode() + .(DataFlowPrivate::ArgumentNode) + .argumentOf(call, any(DirectPosition qualpos | qualpos.getIndex() = -1)) + or + sink.(DataFlowPrivate::OutNode).getCall() = call + ) + } +} From 9ca8a27baeaa36316652be4a3eb93fcdb2499444 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 4 Oct 2024 12:58:04 +0200 Subject: [PATCH 11/15] C/C++: Accept test changes. --- .../dataflow/dataflow-tests/dataflow-consistency.expected | 1 + .../dataflow/dataflow-tests/dataflow-ir-consistency.expected | 1 + .../library-tests/dataflow/fields/dataflow-consistency.expected | 1 + .../dataflow/fields/dataflow-ir-consistency.expected | 1 + .../test/library-tests/syntax-zoo/dataflow-consistency.expected | 1 + .../library-tests/syntax-zoo/dataflow-ir-consistency.expected | 1 + 6 files changed, 6 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index d97abde482eb..8507be51a523 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -186,3 +186,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index 064a53e8d12b..d0d49db4a21f 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -38,3 +38,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected index 0af54dc85709..f50d9f15de5a 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected @@ -195,3 +195,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index e6de5b4991e5..364c6549fe5e 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -28,3 +28,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected index 597d096e7694..9fbef1167a4f 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-consistency.expected @@ -100,3 +100,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel diff --git a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected index e154e42247be..984335d12515 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/dataflow-ir-consistency.expected @@ -37,3 +37,4 @@ identityLocalStep missingArgumentCall multipleArgumentCall lambdaCallEnclosingCallableMismatch +speculativeStepAlreadyHasModel From c20f12fa6cb226a7f940f869dddab7506d3ab0d1 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 16 Oct 2024 11:19:09 +0200 Subject: [PATCH 12/15] Add qldoc. --- .../code/cpp/dataflow/internal/TaintTrackingUtil.qll | 4 ++++ .../code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll | 4 ++++ .../csharp/dataflow/internal/TaintTrackingPrivate.qll | 4 ++++ .../lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll | 4 ++++ .../code/java/dataflow/internal/TaintTrackingUtil.qll | 4 ++++ .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 4 ++++ .../ruby/dataflow/internal/TaintTrackingPrivate.qll | 4 ++++ shared/dataflow/codeql/dataflow/TaintTracking.qll | 8 ++++++++ .../swift/dataflow/internal/TaintTrackingPrivate.qll | 4 ++++ 9 files changed, 40 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index 0b35e74db8c4..493b531a49a9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -282,4 +282,8 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) { private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction } +/** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index 9921be8a147d..b6d332e3d4c2 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -219,6 +219,10 @@ private module SpeculativeTaintFlow { private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as DataFlowDispatch private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowCall call, ArgumentPosition argpos | // TODO: exclude neutrals and anything that has QL modeling. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index c5bf4b082497..1a044a77777d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -185,6 +185,10 @@ private module SpeculativeTaintFlow { exists(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.getACall() = call) } + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowCall call, Call srcCall, ArgumentPosition argpos | not exists(viableCallable(call)) and diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 0ea9dbae200a..5365228e2310 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -434,6 +434,10 @@ import SpeculativeTaintFlow private module SpeculativeTaintFlow { private import semmle.go.dataflow.internal.DataFlowDispatch as DataFlowDispatch + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowPrivate::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | // TODO: exclude neutrals and anything that has QL modeling. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index a3231b4b1cf8..ad770b75a3eb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -690,6 +690,10 @@ private module SpeculativeTaintFlow { .hasName("java.util.function") } + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowCall call, Call srcCall, int argpos | not hasTarget(srcCall) and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index 8c94a4749f76..cc59bc679338 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -226,6 +226,10 @@ private module SpeculativeTaintFlow { private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowDispatch private import semmle.python.dataflow.new.internal.DataFlowPublic as DataFlowPublic + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | // TODO: exclude neutrals and anything that has QL modeling. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index 3c86cccd9628..cae2266e1a2b 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -155,6 +155,10 @@ private module SpeculativeTaintFlow { private import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch private import codeql.ruby.dataflow.internal.DataFlowPublic as DataFlowPublic + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists( DataFlowDispatch::DataFlowCall call, MethodCall srcCall, diff --git a/shared/dataflow/codeql/dataflow/TaintTracking.qll b/shared/dataflow/codeql/dataflow/TaintTracking.qll index beec8f384993..eb98ec2a8096 100644 --- a/shared/dataflow/codeql/dataflow/TaintTracking.qll +++ b/shared/dataflow/codeql/dataflow/TaintTracking.qll @@ -208,6 +208,10 @@ module TaintFlowMake< } } + /** + * Constructs a global taint tracking computation that also allows a given + * maximum number of speculative taint steps. + */ module SpeculativeFlow implements DataFlow::GlobalFlowSig { @@ -229,6 +233,10 @@ module TaintFlowMake< import DataFlowInternal::Impl } + /** + * Constructs a global taint tracking computation using flow state that also + * allows a given maximum number of speculative taint steps. + */ module SpeculativeFlowWithState< DataFlow::StateConfigSig Config, speculationLimitSig/0 speculationLimit> implements DataFlow::GlobalFlowSig diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll index 53c828981ffe..c3f14b03f835 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll @@ -106,6 +106,10 @@ private module SpeculativeTaintFlow { private import codeql.swift.dataflow.internal.DataFlowPublic as DataFlowPublic private import codeql.swift.dataflow.internal.DataFlowPrivate as DataFlowPrivate + /** + * Holds if the additional step from `src` to `sink` should be considered in + * speculative taint flow exploration. + */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | // TODO: exclude neutrals and anything that has QL modeling. From 42d35f8b9d0d469681f5787e0a6eb0cc63986fc2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 16 Oct 2024 14:34:18 +0200 Subject: [PATCH 13/15] Ruby: Exclude some cases that are unlikely library calls. --- .../ruby/dataflow/internal/TaintTrackingPrivate.qll | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll index cae2266e1a2b..3a3eddea63ff 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/TaintTrackingPrivate.qll @@ -162,12 +162,16 @@ private module SpeculativeTaintFlow { predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists( DataFlowDispatch::DataFlowCall call, MethodCall srcCall, - DataFlowDispatch::ArgumentPosition argpos + DataFlowDispatch::ArgumentPosition argpos, MethodCall mc | // TODO: exclude neutrals and anything that has QL modeling. not exists(DataFlowDispatch::viableCallable(call)) and call.asCall().getExpr() = srcCall and - src.(ArgumentNode).argumentOf(call, argpos) + src.(ArgumentNode).argumentOf(call, argpos) and + call.asCall().getExpr() = mc and + not mc instanceof Operation and + not mc instanceof SetterMethodCall and + not mc instanceof ElementReference | not argpos.isSelf() and sink.(DataFlowPublic::PostUpdateNode) From 4153a83a4f0fe6fb7097dd6fae8eddf4a85f3499 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 16 Oct 2024 16:14:51 +0200 Subject: [PATCH 14/15] Python: Add workaround. --- .../python/dataflow/new/internal/TaintTrackingPrivate.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll index cc59bc679338..62f5a76309b4 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll @@ -233,7 +233,12 @@ private module SpeculativeTaintFlow { predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { exists(DataFlowDispatch::DataFlowCall call, DataFlowDispatch::ArgumentPosition argpos | // TODO: exclude neutrals and anything that has QL modeling. - not exists(DataFlowDispatch::viableCallable(call)) and + not exists(DataFlowDispatch::DataFlowCall call0 | + // Workaround for the fact that python currently associates several + // DataFlowCalls with a single call. + src.(DataFlowPublic::ArgumentNode).argumentOf(call0, _) and + exists(DataFlowDispatch::viableCallable(call0)) + ) and call instanceof DataFlowDispatch::PotentialLibraryCall and src.(DataFlowPublic::ArgumentNode).argumentOf(call, argpos) | From 570b0426459741ab545a99d7a4725de216133776 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 30 Oct 2024 15:23:15 +0100 Subject: [PATCH 15/15] Dataflow: Rename SpeculativeFlow to SpeculativeGlobal. --- shared/dataflow/codeql/dataflow/TaintTracking.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/TaintTracking.qll b/shared/dataflow/codeql/dataflow/TaintTracking.qll index eb98ec2a8096..8247255038c0 100644 --- a/shared/dataflow/codeql/dataflow/TaintTracking.qll +++ b/shared/dataflow/codeql/dataflow/TaintTracking.qll @@ -212,7 +212,7 @@ module TaintFlowMake< * Constructs a global taint tracking computation that also allows a given * maximum number of speculative taint steps. */ - module SpeculativeFlow + module SpeculativeGlobal implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -237,7 +237,7 @@ module TaintFlowMake< * Constructs a global taint tracking computation using flow state that also * allows a given maximum number of speculative taint steps. */ - module SpeculativeFlowWithState< + module SpeculativeGlobalWithState< DataFlow::StateConfigSig Config, speculationLimitSig/0 speculationLimit> implements DataFlow::GlobalFlowSig {