Skip to content

Commit

Permalink
Merge branch 'main' into rust-data-flow-models
Browse files Browse the repository at this point in the history
  • Loading branch information
paldepind committed Dec 17, 2024
2 parents ee87d4c + 8efd870 commit d8c301a
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 212 deletions.
119 changes: 66 additions & 53 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,17 @@ module RustDataFlow implements InputSig<Location> {
node instanceof Node::ClosureParameterNode
}

predicate neverSkipInPathGraph(Node node) {
node.getCfgNode() = any(LetStmtCfgNode s).getPat()
or
node.getCfgNode() = any(AssignmentExprCfgNode a).getLhs()
or
exists(MatchExprCfgNode match |
node.asExpr() = match.getScrutinee() or
node.asExpr() = match.getArmPat(_)
)
}

class DataFlowExpr = ExprCfgNode;

/** Gets the node corresponding to `e`. */
Expand Down Expand Up @@ -962,8 +973,8 @@ module RustDataFlow implements InputSig<Location> {
/** Holds if path `p` resolves to variant `v`. */
private predicate pathResolveToVariantCanonicalPath(PathAstNode p, VariantCanonicalPath v) {
exists(CrateOriginOption crate, string path, string name |
resolveExtendedCanonicalPath(p, crate, path + "::" + name) and
v = MkVariantCanonicalPath(crate, path, name)
resolveExtendedCanonicalPath(p, pragma[only_bind_into](crate), path + "::" + name) and
v = MkVariantCanonicalPath(pragma[only_bind_into](crate), path, name)
)
}

Expand Down Expand Up @@ -1086,63 +1097,65 @@ module RustDataFlow implements InputSig<Location> {
)
}

pragma[nomagic]
private predicate storeContentStep(Node node1, Content c, Node node2) {
exists(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos) and
node2.asExpr() = call
)
or
exists(RecordExprCfgNode re, string field |
(
// Expression is for a struct-like enum variant.
recordVariantConstruction(re.getRecordExpr(),
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Expression is for a struct.
structConstruction(re.getRecordExpr(), c.(StructFieldContent).getStructCanonicalPath(field))
) and
node1.asExpr() = re.getFieldExpr(field) and
node2.asExpr() = re
)
or
exists(TupleExprCfgNode tuple |
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
node2.asExpr() = tuple
)
or
c instanceof ArrayElementContent and
node1.asExpr() =
[
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
]
or
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
or
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
c instanceof ArrayElementContent and
assignment.getLhs() = index and
node1.asExpr() = assignment.getRhs() and
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
)
or
exists(RefExprCfgNode ref |
c instanceof ReferenceContent and
node1.asExpr() = ref.getExpr() and
node2.asExpr() = ref
)
or
VariableCapture::storeStep(node1, c, node2)
}

/**
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
* `node2` references an object with a content `c.getAStoreContent()` that
* contains the value of `node1`.
*/
predicate storeStep(Node node1, ContentSet cs, Node node2) {
exists(Content c | c = cs.(SingletonContentSet).getContent() |
exists(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos) and
node2.asExpr() = call
)
or
exists(RecordExprCfgNode re, string field |
(
// Expression is for a struct-like enum variant.
recordVariantConstruction(re.getRecordExpr(),
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Expression is for a struct.
structConstruction(re.getRecordExpr(),
c.(StructFieldContent).getStructCanonicalPath(field))
) and
node1.asExpr() = re.getFieldExpr(field) and
node2.asExpr() = re
)
or
exists(TupleExprCfgNode tuple |
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
node2.asExpr() = tuple
)
or
c instanceof ArrayElementContent and
node1.asExpr() =
[
node2.asExpr().(ArrayRepeatExprCfgNode).getRepeatOperand(),
node2.asExpr().(ArrayListExprCfgNode).getAnExpr()
]
or
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
or
exists(AssignmentExprCfgNode assignment, IndexExprCfgNode index |
c instanceof ArrayElementContent and
assignment.getLhs() = index and
node1.asExpr() = assignment.getRhs() and
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
)
or
exists(RefExprCfgNode ref |
c instanceof ReferenceContent and
node1.asExpr() = ref.getExpr() and
node2.asExpr() = ref
)
or
VariableCapture::storeStep(node1, c, node2)
)
storeContentStep(node1, cs.(SingletonContentSet).getContent(), node2)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
cs, node2.(Node::FlowSummaryNode).getSummaryNode())
Expand Down
20 changes: 15 additions & 5 deletions rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
models
edges
| main.rs:9:13:9:19 | ...: ... | main.rs:9:30:14:1 | { ... } | provenance | |
| main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | provenance | |
| main.rs:26:13:26:21 | source(...) | main.rs:27:22:27:22 | s | provenance | |
| main.rs:27:13:27:23 | sanitize(...) | main.rs:28:10:28:10 | s | provenance | |
| main.rs:9:13:9:19 | ...: ... | main.rs:10:11:10:11 | s | provenance | |
| main.rs:10:11:10:11 | s | main.rs:9:30:14:1 | { ... } | provenance | |
| main.rs:21:9:21:9 | s | main.rs:22:10:22:10 | s | provenance | |
| main.rs:21:13:21:21 | source(...) | main.rs:21:9:21:9 | s | provenance | |
| main.rs:26:9:26:9 | s | main.rs:27:22:27:22 | s | provenance | |
| main.rs:26:13:26:21 | source(...) | main.rs:26:9:26:9 | s | provenance | |
| main.rs:27:9:27:9 | s | main.rs:28:10:28:10 | s | provenance | |
| main.rs:27:13:27:23 | sanitize(...) | main.rs:27:9:27:9 | s | provenance | |
| main.rs:27:22:27:22 | s | main.rs:9:13:9:19 | ...: ... | provenance | |
| main.rs:27:22:27:22 | s | main.rs:27:13:27:23 | sanitize(...) | provenance | |
| main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | provenance | |
| main.rs:32:9:32:9 | s | main.rs:33:10:33:10 | s | provenance | |
| main.rs:32:13:32:21 | source(...) | main.rs:32:9:32:9 | s | provenance | |
nodes
| main.rs:9:13:9:19 | ...: ... | semmle.label | ...: ... |
| main.rs:9:30:14:1 | { ... } | semmle.label | { ... } |
| main.rs:10:11:10:11 | s | semmle.label | s |
| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) |
| main.rs:21:9:21:9 | s | semmle.label | s |
| main.rs:21:13:21:21 | source(...) | semmle.label | source(...) |
| main.rs:22:10:22:10 | s | semmle.label | s |
| main.rs:26:9:26:9 | s | semmle.label | s |
| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) |
| main.rs:27:9:27:9 | s | semmle.label | s |
| main.rs:27:13:27:23 | sanitize(...) | semmle.label | sanitize(...) |
| main.rs:27:22:27:22 | s | semmle.label | s |
| main.rs:28:10:28:10 | s | semmle.label | s |
| main.rs:32:9:32:9 | s | semmle.label | s |
| main.rs:32:13:32:21 | source(...) | semmle.label | source(...) |
| main.rs:33:10:33:10 | s | semmle.label | s |
subpaths
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ edges
| main.rs:11:20:11:52 | if cond {...} else {...} | main.rs:12:10:12:16 | f(...) | provenance | |
| main.rs:11:30:11:39 | source(...) | main.rs:11:20:11:52 | if cond {...} else {...} | provenance | |
| main.rs:16:20:16:23 | ... | main.rs:18:18:18:21 | data | provenance | |
| main.rs:22:13:22:22 | source(...) | main.rs:23:13:23:13 | a | provenance | |
| main.rs:22:9:22:9 | a | main.rs:23:13:23:13 | a | provenance | |
| main.rs:22:13:22:22 | source(...) | main.rs:22:9:22:9 | a | provenance | |
| main.rs:23:13:23:13 | a | main.rs:16:20:16:23 | ... | provenance | |
| main.rs:27:20:27:23 | ... | main.rs:28:9:32:9 | if cond {...} else {...} | provenance | |
| main.rs:33:13:33:22 | source(...) | main.rs:34:21:34:21 | a | provenance | |
| main.rs:34:13:34:22 | f(...) | main.rs:35:10:35:10 | b | provenance | |
| main.rs:33:9:33:9 | a | main.rs:34:21:34:21 | a | provenance | |
| main.rs:33:13:33:22 | source(...) | main.rs:33:9:33:9 | a | provenance | |
| main.rs:34:9:34:9 | b | main.rs:35:10:35:10 | b | provenance | |
| main.rs:34:13:34:22 | f(...) | main.rs:34:9:34:9 | b | provenance | |
| main.rs:34:21:34:21 | a | main.rs:27:20:27:23 | ... | provenance | |
| main.rs:34:21:34:21 | a | main.rs:34:13:34:22 | f(...) | provenance | |
| main.rs:42:16:42:25 | source(...) | main.rs:44:5:44:5 | [post] f [captured capt] | provenance | |
Expand All @@ -20,11 +23,14 @@ nodes
| main.rs:12:10:12:16 | f(...) | semmle.label | f(...) |
| main.rs:16:20:16:23 | ... | semmle.label | ... |
| main.rs:18:18:18:21 | data | semmle.label | data |
| main.rs:22:9:22:9 | a | semmle.label | a |
| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) |
| main.rs:23:13:23:13 | a | semmle.label | a |
| main.rs:27:20:27:23 | ... | semmle.label | ... |
| main.rs:28:9:32:9 | if cond {...} else {...} | semmle.label | if cond {...} else {...} |
| main.rs:33:9:33:9 | a | semmle.label | a |
| main.rs:33:13:33:22 | source(...) | semmle.label | source(...) |
| main.rs:34:9:34:9 | b | semmle.label | b |
| main.rs:34:13:34:22 | f(...) | semmle.label | f(...) |
| main.rs:34:21:34:21 | a | semmle.label | a |
| main.rs:35:10:35:10 | b | semmle.label | b |
Expand Down
36 changes: 27 additions & 9 deletions rust/ql/test/library-tests/dataflow/global/inline-flow.expected
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,59 @@ models
edges
| main.rs:12:28:14:1 | { ... } | main.rs:17:13:17:23 | get_data(...) | provenance | |
| main.rs:13:5:13:13 | source(...) | main.rs:12:28:14:1 | { ... } | provenance | |
| main.rs:17:13:17:23 | get_data(...) | main.rs:18:10:18:10 | a | provenance | |
| main.rs:17:9:17:9 | a | main.rs:18:10:18:10 | a | provenance | |
| main.rs:17:13:17:23 | get_data(...) | main.rs:17:9:17:9 | a | provenance | |
| main.rs:21:12:21:17 | ...: i64 | main.rs:22:10:22:10 | n | provenance | |
| main.rs:26:13:26:21 | source(...) | main.rs:27:13:27:13 | a | provenance | |
| main.rs:26:9:26:9 | a | main.rs:27:13:27:13 | a | provenance | |
| main.rs:26:13:26:21 | source(...) | main.rs:26:9:26:9 | a | provenance | |
| main.rs:27:13:27:13 | a | main.rs:21:12:21:17 | ...: i64 | provenance | |
| main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | provenance | |
| main.rs:35:13:35:21 | source(...) | main.rs:36:26:36:26 | a | provenance | |
| main.rs:36:13:36:27 | pass_through(...) | main.rs:37:10:37:10 | b | provenance | |
| main.rs:35:9:35:9 | a | main.rs:36:26:36:26 | a | provenance | |
| main.rs:35:13:35:21 | source(...) | main.rs:35:9:35:9 | a | provenance | |
| main.rs:36:9:36:9 | b | main.rs:37:10:37:10 | b | provenance | |
| main.rs:36:13:36:27 | pass_through(...) | main.rs:36:9:36:9 | b | provenance | |
| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | provenance | |
| main.rs:36:26:36:26 | a | main.rs:36:13:36:27 | pass_through(...) | provenance | |
| main.rs:41:13:44:6 | pass_through(...) | main.rs:45:10:45:10 | a | provenance | |
| main.rs:41:9:41:9 | a | main.rs:45:10:45:10 | a | provenance | |
| main.rs:41:13:44:6 | pass_through(...) | main.rs:41:9:41:9 | a | provenance | |
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | provenance | |
| main.rs:41:26:44:5 | { ... } | main.rs:41:13:44:6 | pass_through(...) | provenance | |
| main.rs:43:9:43:18 | source(...) | main.rs:41:26:44:5 | { ... } | provenance | |
| main.rs:56:23:56:28 | ...: i64 | main.rs:57:14:57:14 | n | provenance | |
| main.rs:59:31:65:5 | { ... } | main.rs:77:13:77:25 | mn.get_data(...) | provenance | |
| main.rs:63:13:63:21 | source(...) | main.rs:59:31:65:5 | { ... } | provenance | |
| main.rs:66:28:66:33 | ...: i64 | main.rs:66:43:72:5 | { ... } | provenance | |
| main.rs:77:13:77:25 | mn.get_data(...) | main.rs:78:10:78:10 | a | provenance | |
| main.rs:83:13:83:21 | source(...) | main.rs:84:16:84:16 | a | provenance | |
| main.rs:77:9:77:9 | a | main.rs:78:10:78:10 | a | provenance | |
| main.rs:77:13:77:25 | mn.get_data(...) | main.rs:77:9:77:9 | a | provenance | |
| main.rs:83:9:83:9 | a | main.rs:84:16:84:16 | a | provenance | |
| main.rs:83:13:83:21 | source(...) | main.rs:83:9:83:9 | a | provenance | |
| main.rs:84:16:84:16 | a | main.rs:56:23:56:28 | ...: i64 | provenance | |
| main.rs:89:13:89:21 | source(...) | main.rs:90:29:90:29 | a | provenance | |
| main.rs:90:13:90:30 | mn.data_through(...) | main.rs:91:10:91:10 | b | provenance | |
| main.rs:89:9:89:9 | a | main.rs:90:29:90:29 | a | provenance | |
| main.rs:89:13:89:21 | source(...) | main.rs:89:9:89:9 | a | provenance | |
| main.rs:90:9:90:9 | b | main.rs:91:10:91:10 | b | provenance | |
| main.rs:90:13:90:30 | mn.data_through(...) | main.rs:90:9:90:9 | b | provenance | |
| main.rs:90:29:90:29 | a | main.rs:66:28:66:33 | ...: i64 | provenance | |
| main.rs:90:29:90:29 | a | main.rs:90:13:90:30 | mn.data_through(...) | provenance | |
nodes
| main.rs:12:28:14:1 | { ... } | semmle.label | { ... } |
| main.rs:13:5:13:13 | source(...) | semmle.label | source(...) |
| main.rs:17:9:17:9 | a | semmle.label | a |
| main.rs:17:13:17:23 | get_data(...) | semmle.label | get_data(...) |
| main.rs:18:10:18:10 | a | semmle.label | a |
| main.rs:21:12:21:17 | ...: i64 | semmle.label | ...: i64 |
| main.rs:22:10:22:10 | n | semmle.label | n |
| main.rs:26:9:26:9 | a | semmle.label | a |
| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) |
| main.rs:27:13:27:13 | a | semmle.label | a |
| main.rs:30:17:30:22 | ...: i64 | semmle.label | ...: i64 |
| main.rs:30:32:32:1 | { ... } | semmle.label | { ... } |
| main.rs:35:9:35:9 | a | semmle.label | a |
| main.rs:35:13:35:21 | source(...) | semmle.label | source(...) |
| main.rs:36:9:36:9 | b | semmle.label | b |
| main.rs:36:13:36:27 | pass_through(...) | semmle.label | pass_through(...) |
| main.rs:36:26:36:26 | a | semmle.label | a |
| main.rs:37:10:37:10 | b | semmle.label | b |
| main.rs:41:9:41:9 | a | semmle.label | a |
| main.rs:41:13:44:6 | pass_through(...) | semmle.label | pass_through(...) |
| main.rs:41:26:44:5 | { ... } | semmle.label | { ... } |
| main.rs:43:9:43:18 | source(...) | semmle.label | source(...) |
Expand All @@ -51,11 +65,15 @@ nodes
| main.rs:63:13:63:21 | source(...) | semmle.label | source(...) |
| main.rs:66:28:66:33 | ...: i64 | semmle.label | ...: i64 |
| main.rs:66:43:72:5 | { ... } | semmle.label | { ... } |
| main.rs:77:9:77:9 | a | semmle.label | a |
| main.rs:77:13:77:25 | mn.get_data(...) | semmle.label | mn.get_data(...) |
| main.rs:78:10:78:10 | a | semmle.label | a |
| main.rs:83:9:83:9 | a | semmle.label | a |
| main.rs:83:13:83:21 | source(...) | semmle.label | source(...) |
| main.rs:84:16:84:16 | a | semmle.label | a |
| main.rs:89:9:89:9 | a | semmle.label | a |
| main.rs:89:13:89:21 | source(...) | semmle.label | source(...) |
| main.rs:90:9:90:9 | b | semmle.label | b |
| main.rs:90:13:90:30 | mn.data_through(...) | semmle.label | mn.data_through(...) |
| main.rs:90:29:90:29 | a | semmle.label | a |
| main.rs:91:10:91:10 | b | semmle.label | b |
Expand Down
Loading

0 comments on commit d8c301a

Please sign in to comment.