diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 5a5cfd1ca1f6..ffd6f4822af7 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -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. * @@ -1229,6 +1238,12 @@ module RustDataFlow implements InputSig { 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 @@ -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 @@ -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(), diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 5d92958ab4fe..1679ee9f6fb8 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -97,6 +97,10 @@ module Input implements InputSig { c = TTuplePositionContent(pos) and arg = pos.toString() ) + or + result = "Future" and + c = TFutureContent() and + arg = "" ) } diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 3965ac0f16ff..d8af926b4f78 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -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 { diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index 64450d2e73b9..9ef0632466f5 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | | @@ -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 | @@ -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 | @@ -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 |