Skip to content

Commit 4f9f550

Browse files
committed
Rust: Add source models for fs.
1 parent 258c1af commit 4f9f550

File tree

4 files changed

+60
-18
lines changed

4 files changed

+60
-18
lines changed

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,32 @@ class ModeledEnvironmentSource extends EnvironmentSource::Range {
102102
ModeledEnvironmentSource() { sourceNode(this, "environment-source") }
103103
}
104104

105+
/**
106+
* A data flow source corresponding to a file access.
107+
*/
108+
final class FileSource = FileSource::Range;
109+
110+
/**
111+
* An externally modeled source for data from a file access.
112+
*/
113+
class ModeledFileSource extends FileSource::Range {
114+
ModeledFileSource() { sourceNode(this, "file") }
115+
}
116+
117+
/**
118+
* Provides a class for modeling new sources for file accesses.
119+
*/
120+
module FileSource {
121+
/**
122+
* A data flow source corresponding to a file access.
123+
*/
124+
abstract class Range extends ThreatModelSource::Range {
125+
override string getThreatModel() { result = "file" }
126+
127+
override string getSourceType() { result = "FileSource" }
128+
}
129+
}
130+
105131
/**
106132
* A data flow source corresponding to the program's database reads.
107133
*/

rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ extensions:
22
- addsTo:
33
pack: codeql/rust-all
44
extensible: sourceModel
5-
data: []
5+
data:
6+
- ["lang:std", "crate::fs::read", "ReturnValue.Field[crate::result::Result::Ok(0)]", "file", "manual"]
7+
- ["lang:std", "crate::fs::read_to_string", "ReturnValue.Field[crate::result::Result::Ok(0)]", "file", "manual"]
8+
- ["lang:std", "crate::fs::read_link", "ReturnValue.Field[crate::result::Result::Ok(0)]", "file", "manual"]
9+
- ["lang:std", "<crate::fs::DirEntry>::path", "ReturnValue", "file", "manual"]
10+
- ["lang:std", "<crate::fs::DirEntry>::file_name", "ReturnValue", "file", "manual"]
11+
- ["lang:std", "<crate::fs::File>::open", "ReturnValue.Field[crate::result::Result::Ok(0)]", "file", "manual"]
12+
- ["lang:std", "<crate::fs::File>::open_buffered", "ReturnValue.Field[crate::result::Result::Ok(0)]", "file", "manual"]
613
- addsTo:
714
pack: codeql/rust-all
815
extensible: sinkModel
@@ -34,7 +41,6 @@ extensions:
3441
- ["lang:std", "<crate::fs::File>::create_new", "Argument[0]", "path-injection", "manual"]
3542
- ["lang:std", "<crate::fs::File>::open", "Argument[0]", "path-injection", "manual"]
3643
- ["lang:std", "<crate::fs::File>::open_buffered", "Argument[0]", "path-injection", "manual"]
37-
3844
- addsTo:
3945
pack: codeql/rust-all
4046
extensible: summaryModel

rust/ql/test/library-tests/dataflow/sources/TaintSources.expected

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@
2222
| test.rs:80:24:80:35 | ...::get | Flow source 'RemoteSource' of type remote (DEFAULT). |
2323
| test.rs:112:35:112:46 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
2424
| test.rs:119:31:119:42 | send_request | Flow source 'RemoteSource' of type remote (DEFAULT). |
25+
| test.rs:205:31:205:43 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
26+
| test.rs:210:31:210:38 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
27+
| test.rs:215:22:215:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
28+
| test.rs:221:22:221:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
29+
| test.rs:222:27:222:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
30+
| test.rs:228:22:228:34 | ...::read_link | Flow source 'FileSource' of type file (DEFAULT). |
31+
| test.rs:271:20:271:38 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
32+
| test.rs:360:25:360:43 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
33+
| test.rs:361:25:361:43 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
34+
| test.rs:369:25:369:43 | ...::open | Flow source 'FileSource' of type file (DEFAULT). |
2535
| test.rs:386:16:386:29 | ...::args | Flow source 'CommandLineArgs' of type commandargs (DEFAULT). |

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -202,31 +202,31 @@ use std::fs;
202202

203203
fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
204204
{
205-
let buffer: Vec<u8> = std::fs::read("file.bin")?; // $ MISSING: Alert[rust/summary/taint-sources]
206-
sink(buffer); // $ MISSING: hasTaintFlow
205+
let buffer: Vec<u8> = std::fs::read("file.bin")?; // $ Alert[rust/summary/taint-sources]
206+
sink(buffer); // $ hasTaintFlow="file.bin"
207207
}
208208

209209
{
210-
let buffer: Vec<u8> = fs::read("file.bin")?; // $ MISSING: Alert[rust/summary/taint-sources]
211-
sink(buffer); // $ MISSING: hasTaintFlow
210+
let buffer: Vec<u8> = fs::read("file.bin")?; // $ Alert[rust/summary/taint-sources]
211+
sink(buffer); // $ hasTaintFlow="file.bin"
212212
}
213213

214214
{
215-
let buffer = fs::read_to_string("file.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
216-
sink(buffer); // $ MISSING: hasTaintFlow
215+
let buffer = fs::read_to_string("file.txt")?; // $ Alert[rust/summary/taint-sources]
216+
sink(buffer); // $ hasTaintFlow="file.txt"
217217
}
218218

219219
for entry in fs::read_dir("directory")? {
220220
let e = entry?;
221-
let path = e.path(); // $ MISSING: Alert[rust/summary/taint-sources]
222-
let file_name = e.file_name(); // $ MISSING: Alert[rust/summary/taint-sources]
223-
sink(path); // $ MISSING: hasTaintFlow
224-
sink(file_name); // $ MISSING: hasTaintFlow
221+
let path = e.path(); // $ Alert[rust/summary/taint-sources]
222+
let file_name = e.file_name(); // $ Alert[rust/summary/taint-sources]
223+
sink(path); // $ hasTaintFlow
224+
sink(file_name); // $ hasTaintFlow
225225
}
226226

227227
{
228-
let target = fs::read_link("symlink.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
229-
sink(target); // $ MISSING: hasTaintFlow
228+
let target = fs::read_link("symlink.txt")?; // $ Alert[rust/summary/taint-sources]
229+
sink(target); // $ hasTaintFlow="symlink.txt"
230230
}
231231

232232
Ok(())
@@ -268,7 +268,7 @@ fn test_io_fs() -> std::io::Result<()> {
268268

269269
// --- file ---
270270

271-
let mut file = std::fs::File::open("file.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
271+
let mut file = std::fs::File::open("file.txt")?; // $ Alert[rust/summary/taint-sources]
272272

273273
{
274274
let mut buffer = [0u8; 100];
@@ -357,16 +357,16 @@ fn test_io_fs() -> std::io::Result<()> {
357357

358358
{
359359
let mut buffer = String::new();
360-
let mut file1 = std::fs::File::open("file.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
361-
let mut file2 = std::fs::File::open("another_file.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
360+
let mut file1 = std::fs::File::open("file.txt")?; // $ Alert[rust/summary/taint-sources]
361+
let mut file2 = std::fs::File::open("another_file.txt")?; // $ Alert[rust/summary/taint-sources]
362362
let mut reader = file1.chain(file2);
363363
reader.read_to_string(&mut buffer)?;
364364
sink(&buffer); // $ MISSING: hasTaintFlow
365365
}
366366

367367
{
368368
let mut buffer = String::new();
369-
let mut file1 = std::fs::File::open("file.txt")?; // $ MISSING: Alert[rust/summary/taint-sources]
369+
let mut file1 = std::fs::File::open("file.txt")?; // $ Alert[rust/summary/taint-sources]
370370
let mut reader = file1.take(100);
371371
reader.read_to_string(&mut buffer)?;
372372
sink(&buffer); // $ MISSING: hasTaintFlow

0 commit comments

Comments
 (0)