Skip to content

Commit

Permalink
Rust: Basic support for futures and await
Browse files Browse the repository at this point in the history
  • Loading branch information
paldepind committed Feb 5, 2025
1 parent a40cfeb commit 6e99087
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 26 deletions.
19 changes: 18 additions & 1 deletion rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,15 @@ final class ElementContent extends Content, TElementContent {
override Location getLocation() { result instanceof EmptyLocation }
}

/**
* A value that a future resolves to.
*/
final class FutureContent extends Content, TFutureContent {
override string toString() { result = "future" }

override Location getLocation() { result instanceof EmptyLocation }
}

/**
* Content stored at a position in a tuple.
*
Expand Down Expand Up @@ -1229,6 +1238,12 @@ module RustDataFlow implements InputSig<Location> {
c instanceof FunctionCallReturnContent
)
or
exists(AwaitExprCfgNode await |
c instanceof FutureContent and
node1.asExpr() = await.getExpr() and
node2.asExpr() = await
)
or
VariableCapture::readStep(node1, c, node2)
)
or
Expand Down Expand Up @@ -1593,7 +1608,8 @@ private module Cached {
[
any(IndexExprCfgNode i).getBase(), any(FieldExprCfgNode access).getExpr(),
any(TryExprCfgNode try).getExpr(),
any(PrefixExprCfgNode pe | pe.getOperatorName() = "*").getExpr()
any(PrefixExprCfgNode pe | pe.getOperatorName() = "*").getExpr(),
any(AwaitExprCfgNode a).getExpr()
]
} or
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or
Expand Down Expand Up @@ -1649,6 +1665,7 @@ private module Cached {
TVariantInLibTupleFieldContent(VariantInLib::VariantInLib v, int pos) { pos = v.getAPosition() } or
TVariantRecordFieldContent(Variant v, string field) { exists(getVariantRecordField(v, field)) } or
TElementContent() or
TFutureContent() or
TTuplePositionContent(int pos) {
pos in [0 .. max([
any(TuplePat pat).getNumberOfFields(),
Expand Down
4 changes: 4 additions & 0 deletions rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ module Input implements InputSig<Location, RustDataFlow> {
c = TTuplePositionContent(pos) and
arg = pos.toString()
)
or
result = "Future" and
c = TFutureContent() and
arg = ""
)
}

Expand Down
2 changes: 1 addition & 1 deletion rust/ql/test/library-tests/dataflow/models/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ async fn get_async_number(a: i64) -> i64 {
async fn test_get_async_number() {
let s = source(46);
let t = get_async_number(s).await;
sink(t); // $ MISSING: hasValueFlow=46
sink(t); // $ hasValueFlow=46
}

impl MyFieldEnum {
Expand Down
77 changes: 53 additions & 24 deletions rust/ql/test/library-tests/dataflow/models/models.expected
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ models
| 8 | Summary: repo::test; crate::apply; Argument[1].ReturnValue; ReturnValue; value |
| 9 | Summary: repo::test; crate::coerce; Argument[0]; ReturnValue; taint |
| 10 | Summary: repo::test; crate::get_array_element; Argument[0].Element; ReturnValue; value |
| 11 | Summary: repo::test; crate::get_struct_field; Argument[0].Struct[crate::MyStruct::field1]; ReturnValue; value |
| 12 | Summary: repo::test; crate::get_tuple_element; Argument[0].Tuple[0]; ReturnValue; value |
| 13 | Summary: repo::test; crate::get_var_field; Argument[0].Variant[crate::MyFieldEnum::C::field_c]; ReturnValue; value |
| 14 | Summary: repo::test; crate::get_var_pos; Argument[0].Variant[crate::MyPosEnum::A(0)]; ReturnValue; value |
| 15 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.Element; value |
| 16 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Tuple[1]; value |
| 17 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Variant[crate::MyFieldEnum::D::field_d]; value |
| 18 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Variant[crate::MyPosEnum::B(0)]; value |
| 11 | Summary: repo::test; crate::get_async_number; Argument[0]; ReturnValue.Future; value |
| 12 | Summary: repo::test; crate::get_struct_field; Argument[0].Struct[crate::MyStruct::field1]; ReturnValue; value |
| 13 | Summary: repo::test; crate::get_tuple_element; Argument[0].Tuple[0]; ReturnValue; value |
| 14 | Summary: repo::test; crate::get_var_field; Argument[0].Variant[crate::MyFieldEnum::C::field_c]; ReturnValue; value |
| 15 | Summary: repo::test; crate::get_var_pos; Argument[0].Variant[crate::MyPosEnum::A(0)]; ReturnValue; value |
| 16 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.Element; value |
| 17 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Tuple[1]; value |
| 18 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Variant[crate::MyFieldEnum::D::field_d]; value |
| 19 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Variant[crate::MyPosEnum::B(0)]; value |
edges
| main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | |
| main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | |
Expand All @@ -37,8 +38,8 @@ edges
| main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:41:9:41:10 | e1 [A] | provenance | |
| main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | |
| main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | |
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:14 |
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:14 |
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:15 |
| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:15 |
| main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | |
| main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | |
| main.rs:53:13:53:21 | source(...) | main.rs:53:9:53:9 | s | provenance | |
Expand All @@ -47,8 +48,8 @@ edges
| main.rs:54:9:54:10 | e1 [B] | main.rs:55:11:55:12 | e1 [B] | provenance | |
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | |
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:18 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:18 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:19 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:19 |
| main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
| main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
| main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | |
Expand All @@ -65,8 +66,8 @@ edges
| main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:73:9:73:10 | e1 [C] | provenance | |
| main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | |
| main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | |
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:13 |
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:13 |
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:14 |
| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:14 |
| main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | |
| main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | |
| main.rs:85:13:85:21 | source(...) | main.rs:85:9:85:9 | s | provenance | |
Expand All @@ -75,8 +76,8 @@ edges
| main.rs:86:9:86:10 | e1 [D] | main.rs:87:11:87:12 | e1 [D] | provenance | |
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | |
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:17 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:17 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:18 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:18 |
| main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
| main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
| main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | |
Expand All @@ -93,8 +94,8 @@ edges
| main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | main.rs:105:9:105:17 | my_struct [MyStruct.field1] | provenance | |
| main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | |
| main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:11 |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:11 |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 |
| main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | |
| main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | |
| main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | |
Expand All @@ -111,8 +112,8 @@ edges
| main.rs:149:9:149:11 | arr [element] | main.rs:150:10:150:12 | arr [element] | provenance | |
| main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | |
| main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | |
| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:15 |
| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:15 |
| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:16 |
| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:16 |
| main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | |
| main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | |
| main.rs:159:9:159:9 | s | main.rs:160:14:160:14 | s | provenance | |
Expand All @@ -125,8 +126,8 @@ edges
| main.rs:160:13:160:18 | TupleExpr [tuple.0] | main.rs:160:9:160:9 | t [tuple.0] | provenance | |
| main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | |
| main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | |
| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:12 |
| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:12 |
| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:13 |
| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:13 |
| main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | |
| main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | |
| main.rs:172:13:172:22 | source(...) | main.rs:172:9:172:9 | s | provenance | |
Expand All @@ -135,8 +136,8 @@ edges
| main.rs:173:9:173:9 | t [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | |
| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | |
| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:16 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:16 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:17 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:17 |
| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | |
| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | |
| main.rs:184:9:184:9 | s | main.rs:189:11:189:11 | s | provenance | |
Expand Down Expand Up @@ -177,6 +178,18 @@ edges
| main.rs:202:19:202:19 | s | main.rs:201:14:201:14 | ... | provenance | MaD:7 |
| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:7 |
| main.rs:202:19:202:19 | s | main.rs:202:13:202:23 | apply(...) | provenance | MaD:7 |
| main.rs:211:9:211:9 | s | main.rs:212:30:212:30 | s | provenance | |
| main.rs:211:9:211:9 | s | main.rs:212:30:212:30 | s | provenance | |
| main.rs:211:13:211:22 | source(...) | main.rs:211:9:211:9 | s | provenance | |
| main.rs:211:13:211:22 | source(...) | main.rs:211:9:211:9 | s | provenance | |
| main.rs:212:9:212:9 | t | main.rs:213:10:213:10 | t | provenance | |
| main.rs:212:9:212:9 | t | main.rs:213:10:213:10 | t | provenance | |
| main.rs:212:13:212:31 | get_async_number(...) [future] | main.rs:212:13:212:37 | await ... | provenance | |
| main.rs:212:13:212:31 | get_async_number(...) [future] | main.rs:212:13:212:37 | await ... | provenance | |
| main.rs:212:13:212:37 | await ... | main.rs:212:9:212:9 | t | provenance | |
| main.rs:212:13:212:37 | await ... | main.rs:212:9:212:9 | t | provenance | |
| main.rs:212:30:212:30 | s | main.rs:212:13:212:31 | get_async_number(...) [future] | provenance | MaD:11 |
| main.rs:212:30:212:30 | s | main.rs:212:13:212:31 | get_async_number(...) [future] | provenance | MaD:11 |
| main.rs:232:9:232:9 | s [D] | main.rs:233:11:233:11 | s [D] | provenance | |
| main.rs:232:9:232:9 | s [D] | main.rs:233:11:233:11 | s [D] | provenance | |
| main.rs:232:13:232:23 | enum_source | main.rs:232:13:232:27 | enum_source(...) [D] | provenance | Src:MaD:5 |
Expand Down Expand Up @@ -416,6 +429,20 @@ nodes
| main.rs:202:19:202:19 | s | semmle.label | s |
| main.rs:203:10:203:10 | t | semmle.label | t |
| main.rs:203:10:203:10 | t | semmle.label | t |
| main.rs:211:9:211:9 | s | semmle.label | s |
| main.rs:211:9:211:9 | s | semmle.label | s |
| main.rs:211:13:211:22 | source(...) | semmle.label | source(...) |
| main.rs:211:13:211:22 | source(...) | semmle.label | source(...) |
| main.rs:212:9:212:9 | t | semmle.label | t |
| main.rs:212:9:212:9 | t | semmle.label | t |
| main.rs:212:13:212:31 | get_async_number(...) [future] | semmle.label | get_async_number(...) [future] |
| main.rs:212:13:212:31 | get_async_number(...) [future] | semmle.label | get_async_number(...) [future] |
| main.rs:212:13:212:37 | await ... | semmle.label | await ... |
| main.rs:212:13:212:37 | await ... | semmle.label | await ... |
| main.rs:212:30:212:30 | s | semmle.label | s |
| main.rs:212:30:212:30 | s | semmle.label | s |
| main.rs:213:10:213:10 | t | semmle.label | t |
| main.rs:213:10:213:10 | t | semmle.label | t |
| main.rs:232:9:232:9 | s [D] | semmle.label | s [D] |
| main.rs:232:9:232:9 | s [D] | semmle.label | s [D] |
| main.rs:232:13:232:23 | enum_source | semmle.label | enum_source |
Expand Down Expand Up @@ -519,6 +546,8 @@ invalidSpecComponent
| main.rs:196:10:196:10 | t | main.rs:193:13:193:22 | source(...) | main.rs:196:10:196:10 | t | $@ | main.rs:193:13:193:22 | source(...) | source(...) |
| main.rs:203:10:203:10 | t | main.rs:200:13:200:22 | source(...) | main.rs:203:10:203:10 | t | $@ | main.rs:200:13:200:22 | source(...) | source(...) |
| main.rs:203:10:203:10 | t | main.rs:200:13:200:22 | source(...) | main.rs:203:10:203:10 | t | $@ | main.rs:200:13:200:22 | source(...) | source(...) |
| main.rs:213:10:213:10 | t | main.rs:211:13:211:22 | source(...) | main.rs:213:10:213:10 | t | $@ | main.rs:211:13:211:22 | source(...) | source(...) |
| main.rs:213:10:213:10 | t | main.rs:211:13:211:22 | source(...) | main.rs:213:10:213:10 | t | $@ | main.rs:211:13:211:22 | source(...) | source(...) |
| main.rs:235:47:235:47 | i | main.rs:232:13:232:23 | enum_source | main.rs:235:47:235:47 | i | $@ | main.rs:232:13:232:23 | enum_source | enum_source |
| main.rs:235:47:235:47 | i | main.rs:232:13:232:23 | enum_source | main.rs:235:47:235:47 | i | $@ | main.rs:232:13:232:23 | enum_source | enum_source |
| main.rs:243:47:243:47 | i | main.rs:241:15:241:20 | source | main.rs:243:47:243:47 | i | $@ | main.rs:241:15:241:20 | source | source |
Expand Down

0 comments on commit 6e99087

Please sign in to comment.