Skip to content

Commit e64f139

Browse files
committed
Rust: Model std::env.
1 parent 3747698 commit e64f139

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

rust/ql/lib/codeql/rust/Concepts.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,32 @@ class ActiveThreatModelSource extends ThreatModelSource {
4747
ActiveThreatModelSource() { currentThreatModel(this.getThreatModel()) }
4848
}
4949

50+
/**
51+
* A data flow source corresponding to the program's command line arguments or path.
52+
*/
53+
class CommandLineArgsSource extends ThreatModelSource instanceof CommandLineArgsSource::Range { }
54+
55+
module CommandLineArgsSource {
56+
abstract class Range extends ThreatModelSource::Range {
57+
override string getThreatModel() { result = "commandargs" }
58+
59+
override string getSourceType() { result = "CommandLineArgs" }
60+
}
61+
}
62+
63+
/**
64+
* A data flow source corresponding to the program's environment.
65+
*/
66+
class EnvironmentSource extends ThreatModelSource instanceof EnvironmentSource::Range { }
67+
68+
module EnvironmentSource {
69+
abstract class Range extends ThreatModelSource::Range {
70+
override string getThreatModel() { result = "environment" }
71+
72+
override string getSourceType() { result = "EnvironmentSource" }
73+
}
74+
}
75+
5076
/**
5177
* A data-flow node that constructs a SQL statement.
5278
*
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/**
22
* This file imports all models of frameworks and libraries.
33
*/
4+
5+
private import codeql.rust.frameworks.stdlib.Env
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Provides modeling for the `std::env` library.
3+
*/
4+
5+
private import rust
6+
private import codeql.rust.Concepts
7+
8+
/**
9+
* A call to `std::env::args` or `std::env::args_os`.
10+
*/
11+
private class StdEnvArgs extends CommandLineArgsSource::Range {
12+
StdEnvArgs() {
13+
this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::args", "crate::env::args_os"]
14+
}
15+
}
16+
17+
/**
18+
* A call to `std::env::current_dir`, `std::env::current_exe` or `std::env::home_dir`.
19+
*/
20+
private class StdEnvDir extends CommandLineArgsSource::Range {
21+
StdEnvDir() {
22+
this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"]
23+
}
24+
}
25+
26+
/**
27+
* A call to `std::env::var`, `std::env::var_os`, `std::env::vars` or `std::env::vars_os`.
28+
*/
29+
private class StdEnvVar extends EnvironmentSource::Range {
30+
StdEnvVar() {
31+
this.asExpr().(CallExpr).getExpr().(PathExpr).getPath().getResolvedPath() = ["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"]
32+
}
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
| test.rs:8:10:8:30 | CallExpr | EnvironmentSource (environment) |
2+
| test.rs:9:10:9:33 | CallExpr | EnvironmentSource (environment) |
3+
| test.rs:11:16:11:36 | CallExpr | EnvironmentSource (environment) |
4+
| test.rs:12:16:12:39 | CallExpr | EnvironmentSource (environment) |
5+
| test.rs:17:25:17:40 | CallExpr | EnvironmentSource (environment) |
6+
| test.rs:22:25:22:43 | CallExpr | EnvironmentSource (environment) |
7+
| test.rs:29:29:29:44 | CallExpr | CommandLineArgs (commandargs) |
8+
| test.rs:32:16:32:31 | CallExpr | CommandLineArgs (commandargs) |
9+
| test.rs:33:16:33:34 | CallExpr | CommandLineArgs (commandargs) |
10+
| test.rs:40:16:40:31 | CallExpr | CommandLineArgs (commandargs) |
11+
| test.rs:44:16:44:34 | CallExpr | CommandLineArgs (commandargs) |
12+
| test.rs:50:15:50:37 | CallExpr | CommandLineArgs (commandargs) |
13+
| test.rs:51:15:51:37 | CallExpr | CommandLineArgs (commandargs) |
14+
| test.rs:52:16:52:35 | CallExpr | CommandLineArgs (commandargs) |

rust/ql/test/library-tests/dataflow/sources/test.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,51 @@ fn sink<T>(_: T) { }
55
// --- tests ---
66

77
fn test_env_vars() {
8-
sink(std::env::var("HOME")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow
9-
sink(std::env::var_os("PATH")); // $ MISSING: Alert[rust/summary/taint-sources] hasTaintFlow
8+
sink(std::env::var("HOME")); // $ Alert[rust/summary/taint-sources] hasTaintFlow
9+
sink(std::env::var_os("PATH")); // $ Alert[rust/summary/taint-sources] hasTaintFlow
1010

11-
let var1 = std::env::var("HOME").expect("HOME not set"); // $ MISSING: Alert[rust/summary/taint-sources]
12-
let var2 = std::env::var_os("PATH").unwrap(); // $ MISSING: Alert[rust/summary/taint-sources]
11+
let var1 = std::env::var("HOME").expect("HOME not set"); // $ Alert[rust/summary/taint-sources]
12+
let var2 = std::env::var_os("PATH").unwrap(); // $ Alert[rust/summary/taint-sources]
1313

1414
sink(var1); // $ MISSING: hasTaintFlow
1515
sink(var2); // $ MISSING: hasTaintFlow
1616

17-
for (key, value) in std::env::vars() { // $ MISSING: Alert[rust/summary/taint-sources]
17+
for (key, value) in std::env::vars() { // $ Alert[rust/summary/taint-sources]
1818
sink(key); // $ MISSING: hasTaintFlow
1919
sink(value); // $ MISSING: hasTaintFlow
2020
}
2121

22-
for (key, value) in std::env::vars_os() { // $ MISSING: Alert[rust/summary/taint-sources]
22+
for (key, value) in std::env::vars_os() { // $ Alert[rust/summary/taint-sources]
2323
sink(key); // $ MISSING: hasTaintFlow
2424
sink(value); // $ MISSING: hasTaintFlow
2525
}
2626
}
2727

2828
fn test_env_args() {
29-
let args: Vec<String> = std::env::args().collect(); // $ MISSING: Alert[rust/summary/taint-sources]
29+
let args: Vec<String> = std::env::args().collect(); // $ Alert[rust/summary/taint-sources]
3030
let my_path = &args[0];
3131
let arg1 = &args[1];
32-
let arg2 = std::env::args().nth(2).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources]
33-
let arg3 = std::env::args_os().nth(3).unwrap(); // $ MISSING: Alert[rust/summary/taint-sources]
32+
let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources]
33+
let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources]
3434

3535
sink(my_path); // $ MISSING: hasTaintFlow
3636
sink(arg1); // $ MISSING: hasTaintFlow
3737
sink(arg2); // $ MISSING: hasTaintFlow
3838
sink(arg3); // $ MISSING: hasTaintFlow
3939

40-
for arg in std::env::args() { // $ MISSING: Alert[rust/summary/taint-sources]
40+
for arg in std::env::args() { // $ Alert[rust/summary/taint-sources]
4141
sink(arg); // $ MISSING: hasTaintFlow
4242
}
4343

44-
for arg in std::env::args_os() { // $ MISSING: Alert[rust/summary/taint-sources]
44+
for arg in std::env::args_os() { // $ Alert[rust/summary/taint-sources]
4545
sink(arg); // $ MISSING: hasTaintFlow
4646
}
4747
}
4848

4949
fn test_env_dirs() {
50-
let dir = std::env::current_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources]
51-
let exe = std::env::current_exe().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources]
52-
let home = std::env::home_dir().expect("FAILED"); // $ MISSING: Alert[rust/summary/taint-sources]
50+
let dir = std::env::current_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
51+
let exe = std::env::current_exe().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
52+
let home = std::env::home_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
5353

5454
sink(dir); // $ MISSING: hasTaintFlow
5555
sink(exe); // $ MISSING: hasTaintFlow

0 commit comments

Comments
 (0)