Skip to content

Commit 0bebfa6

Browse files
authored
Merge pull request github#18130 from hvitved/rust/flow-summary-impl
Rust: Adopt shared flow summaries library
2 parents 1e1674a + 52dc79e commit 0bebfa6

File tree

15 files changed

+875
-248
lines changed

15 files changed

+875
-248
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,11 +731,9 @@ module LocalFlow {
731731
or
732732
node2 = node1.(LocalFunctionCreationNode).getAnAccess(true)
733733
or
734-
node1 =
735-
unique(FlowSummaryNode n1 |
736-
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
737-
node2.(FlowSummaryNode).getSummaryNode(), true, _)
738-
)
734+
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
735+
.(FlowSummaryNode)
736+
.getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode())
739737
}
740738
}
741739

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,8 @@ predicate localMustFlowStep(Node node1, Node node2) {
160160
or
161161
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
162162
or
163-
node1 =
164-
unique(FlowSummaryNode n1 |
165-
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
166-
node2.(FlowSummaryNode).getSummaryNode(), true, _)
167-
)
163+
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1.(FlowSummaryNode).getSummaryNode(),
164+
node2.(FlowSummaryNode).getSummaryNode())
168165
}
169166

170167
import Cached

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,9 @@ module LocalFlow {
175175
or
176176
node1 = node2.(ImplicitBlockArgumentNode).getParameterNode(true)
177177
or
178-
node1 =
179-
unique(FlowSummaryNode n1 |
180-
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
181-
node2.(FlowSummaryNode).getSummaryNode(), true, _)
182-
)
178+
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
179+
.(FlowSummaryNode)
180+
.getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode())
183181
}
184182
}
185183

rust/ql/lib/codeql/rust/dataflow/DataFlow.qll

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ private import DataFlowImpl::Node as Node
1515
module DataFlow {
1616
final class Node = Node::Node;
1717

18-
final class ParameterNode = Node::ParameterNode;
18+
/**
19+
* The value of a parameter at function entry, viewed as a node in a data
20+
* flow graph.
21+
*/
22+
final class ParameterNode extends Node instanceof Node::SourceParameterNode {
23+
/** Gets the parameter that this node corresponds to. */
24+
ParamBase getParameter() { result = super.getParameter().getParamBase() }
25+
}
1926

2027
final class PostUpdateNode = Node::PostUpdateNode;
2128

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/** Provides classes and predicates for defining flow summaries. */
2+
3+
private import rust
4+
private import internal.FlowSummaryImpl as Impl
5+
private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl
6+
7+
// import all instances below
8+
private module Summaries {
9+
private import codeql.rust.Frameworks
10+
11+
// TODO: Use models-as-data when it's available
12+
private class UnwrapSummary extends SummarizedCallable::Range {
13+
UnwrapSummary() { this = "lang:core::_::<crate::option::Option>::unwrap" }
14+
15+
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
16+
input = "Argument[self].Variant[crate::std::option::Option::Some(0)]" and
17+
output = "ReturnValue" and
18+
preservesValue = true
19+
}
20+
}
21+
}
22+
23+
/** Provides the `Range` class used to define the extent of `LibraryCallable`. */
24+
module LibraryCallable {
25+
/** A callable defined in library code, identified by a unique string. */
26+
abstract class Range extends string {
27+
bindingset[this]
28+
Range() { any() }
29+
30+
/** Gets a call to this library callable. */
31+
CallExprBase getACall() {
32+
exists(Resolvable r, string crate |
33+
r = CallExprBaseImpl::getCallResolvable(result) and
34+
this = crate + r.getResolvedPath()
35+
|
36+
crate = r.getResolvedCrateOrigin() + "::_::"
37+
or
38+
not r.hasResolvedCrateOrigin() and
39+
crate = ""
40+
)
41+
}
42+
}
43+
}
44+
45+
final class LibraryCallable = LibraryCallable::Range;
46+
47+
/** Provides the `Range` class used to define the extent of `SummarizedCallable`. */
48+
module SummarizedCallable {
49+
/** A callable with a flow summary, identified by a unique string. */
50+
abstract class Range extends LibraryCallable::Range, Impl::Public::SummarizedCallable {
51+
bindingset[this]
52+
Range() { any() }
53+
54+
override predicate propagatesFlow(
55+
string input, string output, boolean preservesValue, string model
56+
) {
57+
this.propagatesFlow(input, output, preservesValue) and model = ""
58+
}
59+
60+
/**
61+
* Holds if data may flow from `input` to `output` through this callable.
62+
*
63+
* `preservesValue` indicates whether this is a value-preserving step or a taint-step.
64+
*/
65+
abstract predicate propagatesFlow(string input, string output, boolean preservesValue);
66+
}
67+
}
68+
69+
final class SummarizedCallable = SummarizedCallable::Range;

0 commit comments

Comments
 (0)