Skip to content

Commit 49be5fd

Browse files
authored
Merge pull request github#12250 from geoffw0/filemanagersource
Swift: Taint sources for FileManager
2 parents efc75e0 + 7a9bbb1 commit 49be5fd

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ private module Frameworks {
8181
private import codeql.swift.frameworks.StandardLibrary.Collection
8282
private import codeql.swift.frameworks.StandardLibrary.CustomUrlSchemes
8383
private import codeql.swift.frameworks.StandardLibrary.Data
84+
private import codeql.swift.frameworks.StandardLibrary.FileManager
8485
private import codeql.swift.frameworks.StandardLibrary.FilePath
8586
private import codeql.swift.frameworks.StandardLibrary.InputStream
8687
private import codeql.swift.frameworks.StandardLibrary.NsData
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Provides models for the `FileManager` Swift class.
3+
*/
4+
5+
import swift
6+
private import codeql.swift.dataflow.ExternalFlow
7+
8+
/**
9+
* A model for `FileManager` members that are flow sources.
10+
*/
11+
private class FileManagerSource extends SourceModelCsv {
12+
override predicate row(string row) {
13+
row =
14+
[
15+
";FileManager;true;contentsOfDirectory(at:includingPropertiesForKeys:options:);;;ReturnValue;local",
16+
";FileManager;true;contentsOfDirectory(atPath:);;;ReturnValue;local",
17+
";FileManager;true;directoryContents(atPath:);;;ReturnValue;local",
18+
";FileManager;true;subpathsOfDirectory(atPath:);;;ReturnValue;local",
19+
";FileManager;true;subpaths(atPath:);;;ReturnValue;local",
20+
";FileManager;true;destinationOfSymbolicLink(atPath:);;;ReturnValue;local",
21+
";FileManager;true;pathContentOfSymbolicLink(atPath:);;;ReturnValue;local",
22+
";FileManager;true;contents(atPath:);;;ReturnValue;local"
23+
]
24+
}
25+
}

swift/ql/test/library-tests/dataflow/flowsources/FlowSources.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@
3838
| file://:0:0:0:0 | .source1 | external |
3939
| file://:0:0:0:0 | .source4 | external |
4040
| file://:0:0:0:0 | .source9 | external |
41+
| filemanager.swift:37:23:37:86 | call to contentsOfDirectory(at:includingPropertiesForKeys:options:) | external |
42+
| filemanager.swift:38:23:38:58 | call to contentsOfDirectory(atPath:) | external |
43+
| filemanager.swift:39:19:39:52 | call to directoryContents(atPath:) | external |
44+
| filemanager.swift:41:23:41:58 | call to subpathsOfDirectory(atPath:) | external |
45+
| filemanager.swift:42:19:42:43 | call to subpaths(atPath:) | external |
46+
| filemanager.swift:44:19:44:60 | call to destinationOfSymbolicLink(atPath:) | external |
47+
| filemanager.swift:45:15:45:56 | call to pathContentOfSymbolicLink(atPath:) | external |
48+
| filemanager.swift:47:14:47:38 | call to contents(atPath:) | external |
4149
| generics.swift:10:9:10:16 | .source1 | external |
4250
| generics.swift:11:9:11:16 | .source2 | external |
4351
| generics.swift:12:9:12:24 | call to source3() | external |
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// --- stubs ---
2+
3+
class NSObject {
4+
}
5+
6+
struct URL {
7+
}
8+
9+
struct URLResourceKey {
10+
}
11+
12+
struct Data {
13+
}
14+
15+
class FileManager : NSObject {
16+
struct DirectoryEnumerationOptions : OptionSet{
17+
let rawValue: Int
18+
}
19+
20+
func contentsOfDirectory(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions = []) throws -> [URL] { return [] }
21+
func contentsOfDirectory(atPath path: String) throws -> [String] { return [] }
22+
func directoryContents(atPath path: String) -> [Any]? { return [] } // returns array of NSString
23+
func subpathsOfDirectory(atPath path: String) throws -> [String] { return [] }
24+
func subpaths(atPath path: String) -> [String]? { return [] }
25+
26+
func destinationOfSymbolicLink(atPath path: String) throws -> String { return "" }
27+
func pathContentOfSymbolicLink(atPath path: String) -> String? { return "" }
28+
29+
func contents(atPath path: String) -> Data? { return nil }
30+
}
31+
32+
// --- tests ---
33+
34+
func testFileHandle(fm: FileManager, url: URL, path: String) {
35+
do
36+
{
37+
let contents1 = try fm.contentsOfDirectory(at: url, includingPropertiesForKeys: nil) // SOURCE
38+
let contents2 = try fm.contentsOfDirectory(atPath: path) // SOURCE
39+
let contents3 = fm.directoryContents(atPath: path)! // SOURCE
40+
41+
let subpaths1 = try fm.subpathsOfDirectory(atPath: path) // SOURCE
42+
let subpaths2 = fm.subpaths(atPath: path)! // SOURCE
43+
44+
let link1 = try fm.destinationOfSymbolicLink(atPath: path) // SOURCE
45+
let link2 = fm.pathContentOfSymbolicLink(atPath: path)! // SOURCE
46+
47+
let data = fm.contents(atPath: path)! // SOURCE
48+
} catch {
49+
// ...
50+
}
51+
}

0 commit comments

Comments
 (0)