Skip to content

Commit 00302dc

Browse files
committed
Swift: Model NSObject.
1 parent 7e8645a commit 00302dc

File tree

5 files changed

+72
-4
lines changed

5 files changed

+72
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ private module Frameworks {
8484
private import codeql.swift.frameworks.StandardLibrary.FilePath
8585
private import codeql.swift.frameworks.StandardLibrary.InputStream
8686
private import codeql.swift.frameworks.StandardLibrary.NsData
87+
private import codeql.swift.frameworks.StandardLibrary.NsObject
8788
private import codeql.swift.frameworks.StandardLibrary.NsString
8889
private import codeql.swift.frameworks.StandardLibrary.NsUrl
8990
private import codeql.swift.frameworks.StandardLibrary.Sequence
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Provides models for `NSObject` and related Swift classes.
3+
*/
4+
5+
import swift
6+
private import codeql.swift.dataflow.DataFlow
7+
private import codeql.swift.dataflow.ExternalFlow
8+
private import codeql.swift.dataflow.FlowSteps
9+
10+
/**
11+
* A model for `NSObject`, `NSCopying` and `NSMutableCopying` members that permit taint flow.
12+
*/
13+
private class NsObjectSummaries extends SummaryModelCsv {
14+
override predicate row(string row) {
15+
row = [
16+
";NSObject;true;copy();;;Argument[-1];ReturnValue;taint",
17+
";NSObject;true;mutableCopy();;;Argument[-1];ReturnValue;taint",
18+
";NSCopying;true;copy(with:);;;Argument[-1];ReturnValue;taint",
19+
";NSMutableCopying;true;mutableCopy(with:);;;Argument[-1];ReturnValue;taint",
20+
]
21+
}
22+
}

swift/ql/test/library-tests/dataflow/taint/LocalTaint.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,11 +1144,15 @@
11441144
| nsstring.swift:383:7:383:7 | SSA def(str20) | nsstring.swift:385:13:385:13 | str20 |
11451145
| nsstring.swift:383:15:383:30 | call to sourceNSString() | nsstring.swift:383:7:383:7 | SSA def(str20) |
11461146
| nsstring.swift:385:13:385:13 | [post] str20 | nsstring.swift:386:13:386:13 | str20 |
1147+
| nsstring.swift:385:13:385:13 | str20 | nsstring.swift:385:13:385:24 | call to copy() |
11471148
| nsstring.swift:385:13:385:13 | str20 | nsstring.swift:386:13:386:13 | str20 |
11481149
| nsstring.swift:386:13:386:13 | [post] str20 | nsstring.swift:387:13:387:13 | str20 |
1150+
| nsstring.swift:386:13:386:13 | str20 | nsstring.swift:386:13:386:31 | call to mutableCopy() |
11491151
| nsstring.swift:386:13:386:13 | str20 | nsstring.swift:387:13:387:13 | str20 |
11501152
| nsstring.swift:387:13:387:13 | [post] str20 | nsstring.swift:388:13:388:13 | str20 |
1153+
| nsstring.swift:387:13:387:13 | str20 | nsstring.swift:387:13:387:33 | call to copy(with:) |
11511154
| nsstring.swift:387:13:387:13 | str20 | nsstring.swift:388:13:388:13 | str20 |
1155+
| nsstring.swift:388:13:388:13 | str20 | nsstring.swift:388:13:388:40 | call to mutableCopy(with:) |
11521156
| nsstring.swift:392:13:392:35 | call to sourceNSMutableString() | nsstring.swift:392:13:392:58 | call to capitalized(with:) |
11531157
| nsstring.swift:394:7:394:7 | SSA def(str30) | nsstring.swift:395:13:395:13 | str30 |
11541158
| nsstring.swift:394:15:394:41 | call to NSMutableString.init(string:) | nsstring.swift:394:7:394:7 | SSA def(str30) |

swift/ql/test/library-tests/dataflow/taint/Taint.expected

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ edges
331331
| nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes |
332332
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:13:9:13:9 | self : |
333333
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | nsmutabledata.swift:49:15:49:37 | .mutableBytes |
334+
| nsstring.swift:7:3:7:33 | [summary param] this in copy() : | file://:0:0:0:0 | [summary] to write: return (return) in copy() : |
335+
| nsstring.swift:8:3:8:40 | [summary param] this in mutableCopy() : | file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy() : |
334336
| nsstring.swift:31:3:31:58 | [summary param] 0 in NSString.init(characters:length:) : | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(characters:length:) : |
335337
| nsstring.swift:32:3:32:113 | [summary param] 0 in NSString.init(charactersNoCopy:length:freeWhenDone:) : | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(charactersNoCopy:length:freeWhenDone:) : |
336338
| nsstring.swift:33:3:33:33 | [summary param] 0 in NSString.init(string:) : | file://:0:0:0:0 | [summary] to write: return (return) in NSString.init(string:) : |
@@ -350,6 +352,8 @@ edges
350352
| nsstring.swift:49:15:49:73 | [summary param] 0 in Self.init(data:encoding:) : | file://:0:0:0:0 | [summary] to write: return (return) in Self.init(data:encoding:) : |
351353
| nsstring.swift:50:15:50:74 | [summary param] 0 in Self.init(contentsOfFile:) : | file://:0:0:0:0 | [summary] to write: return (return) in Self.init(contentsOfFile:) : |
352354
| nsstring.swift:51:15:51:66 | [summary param] 0 in Self.init(contentsOf:) : | file://:0:0:0:0 | [summary] to write: return (return) in Self.init(contentsOf:) : |
355+
| nsstring.swift:53:3:53:57 | [summary param] this in copy(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in copy(with:) : |
356+
| nsstring.swift:54:3:54:64 | [summary param] this in mutableCopy(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy(with:) : |
353357
| nsstring.swift:56:3:56:110 | [summary param] 0 in localizedStringWithFormat(_:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in localizedStringWithFormat(_:_:) : |
354358
| nsstring.swift:57:3:57:78 | [summary param] 0 in path(withComponents:) : | file://:0:0:0:0 | [summary] to write: return (return) in path(withComponents:) : |
355359
| nsstring.swift:58:3:58:83 | [summary param] 0 in string(withCString:) : | file://:0:0:0:0 | [summary] to write: return (return) in string(withCString:) : |
@@ -571,6 +575,18 @@ edges
571575
| nsstring.swift:334:3:334:18 | call to sourceNSString() : | nsstring.swift:66:3:66:281 | [summary param] this in getBytes(_:maxLength:usedLength:encoding:options:range:remaining:) : |
572576
| nsstring.swift:334:3:334:18 | call to sourceNSString() : | nsstring.swift:334:29:334:29 | [post] ptr3 : |
573577
| nsstring.swift:334:29:334:29 | [post] ptr3 : | nsstring.swift:335:13:335:13 | ptr3 |
578+
| nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:385:13:385:13 | str20 : |
579+
| nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:386:13:386:13 | str20 : |
580+
| nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:387:13:387:13 | str20 : |
581+
| nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:388:13:388:13 | str20 : |
582+
| nsstring.swift:385:13:385:13 | str20 : | nsstring.swift:7:3:7:33 | [summary param] this in copy() : |
583+
| nsstring.swift:385:13:385:13 | str20 : | nsstring.swift:385:13:385:24 | call to copy() |
584+
| nsstring.swift:386:13:386:13 | str20 : | nsstring.swift:8:3:8:40 | [summary param] this in mutableCopy() : |
585+
| nsstring.swift:386:13:386:13 | str20 : | nsstring.swift:386:13:386:31 | call to mutableCopy() |
586+
| nsstring.swift:387:13:387:13 | str20 : | nsstring.swift:53:3:53:57 | [summary param] this in copy(with:) : |
587+
| nsstring.swift:387:13:387:13 | str20 : | nsstring.swift:387:13:387:33 | call to copy(with:) |
588+
| nsstring.swift:388:13:388:13 | str20 : | nsstring.swift:54:3:54:64 | [summary param] this in mutableCopy(with:) : |
589+
| nsstring.swift:388:13:388:13 | str20 : | nsstring.swift:388:13:388:40 | call to mutableCopy(with:) |
574590
| nsstring.swift:392:13:392:35 | call to sourceNSMutableString() : | nsstring.swift:77:3:77:64 | [summary param] this in capitalized(with:) : |
575591
| nsstring.swift:392:13:392:35 | call to sourceNSMutableString() : | nsstring.swift:392:13:392:58 | call to capitalized(with:) |
576592
| nsstring.swift:396:3:396:3 | [post] str30 : | nsstring.swift:397:13:397:13 | str30 |
@@ -1502,6 +1518,8 @@ nodes
15021518
| file://:0:0:0:0 | [summary] to write: return (return) in components(separatedBy:) : | semmle.label | [summary] to write: return (return) in components(separatedBy:) : |
15031519
| file://:0:0:0:0 | [summary] to write: return (return) in components(separatedBy:) : | semmle.label | [summary] to write: return (return) in components(separatedBy:) : |
15041520
| file://:0:0:0:0 | [summary] to write: return (return) in compressed(using:) : | semmle.label | [summary] to write: return (return) in compressed(using:) : |
1521+
| file://:0:0:0:0 | [summary] to write: return (return) in copy() : | semmle.label | [summary] to write: return (return) in copy() : |
1522+
| file://:0:0:0:0 | [summary] to write: return (return) in copy(with:) : | semmle.label | [summary] to write: return (return) in copy(with:) : |
15051523
| file://:0:0:0:0 | [summary] to write: return (return) in data(using:) : | semmle.label | [summary] to write: return (return) in data(using:) : |
15061524
| file://:0:0:0:0 | [summary] to write: return (return) in data(using:allowLossyConversion:) : | semmle.label | [summary] to write: return (return) in data(using:allowLossyConversion:) : |
15071525
| file://:0:0:0:0 | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : | semmle.label | [summary] to write: return (return) in dataWithContentsOfMappedFile(_:) : |
@@ -1520,6 +1538,8 @@ nodes
15201538
| file://:0:0:0:0 | [summary] to write: return (return) in lowercased(with:) : | semmle.label | [summary] to write: return (return) in lowercased(with:) : |
15211539
| file://:0:0:0:0 | [summary] to write: return (return) in lowercased(with:) : | semmle.label | [summary] to write: return (return) in lowercased(with:) : |
15221540
| file://:0:0:0:0 | [summary] to write: return (return) in map(_:) : | semmle.label | [summary] to write: return (return) in map(_:) : |
1541+
| file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy() : | semmle.label | [summary] to write: return (return) in mutableCopy() : |
1542+
| file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy(with:) : | semmle.label | [summary] to write: return (return) in mutableCopy(with:) : |
15231543
| file://:0:0:0:0 | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : | semmle.label | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : |
15241544
| file://:0:0:0:0 | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : | semmle.label | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : |
15251545
| file://:0:0:0:0 | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : | semmle.label | [summary] to write: return (return) in padding(toLength:withPad:startingAt:) : |
@@ -1713,6 +1733,8 @@ nodes
17131733
| nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : |
17141734
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : |
17151735
| nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes |
1736+
| nsstring.swift:7:3:7:33 | [summary param] this in copy() : | semmle.label | [summary param] this in copy() : |
1737+
| nsstring.swift:8:3:8:40 | [summary param] this in mutableCopy() : | semmle.label | [summary param] this in mutableCopy() : |
17161738
| nsstring.swift:31:3:31:58 | [summary param] 0 in NSString.init(characters:length:) : | semmle.label | [summary param] 0 in NSString.init(characters:length:) : |
17171739
| nsstring.swift:32:3:32:113 | [summary param] 0 in NSString.init(charactersNoCopy:length:freeWhenDone:) : | semmle.label | [summary param] 0 in NSString.init(charactersNoCopy:length:freeWhenDone:) : |
17181740
| nsstring.swift:33:3:33:33 | [summary param] 0 in NSString.init(string:) : | semmle.label | [summary param] 0 in NSString.init(string:) : |
@@ -1732,6 +1754,8 @@ nodes
17321754
| nsstring.swift:49:15:49:73 | [summary param] 0 in Self.init(data:encoding:) : | semmle.label | [summary param] 0 in Self.init(data:encoding:) : |
17331755
| nsstring.swift:50:15:50:74 | [summary param] 0 in Self.init(contentsOfFile:) : | semmle.label | [summary param] 0 in Self.init(contentsOfFile:) : |
17341756
| nsstring.swift:51:15:51:66 | [summary param] 0 in Self.init(contentsOf:) : | semmle.label | [summary param] 0 in Self.init(contentsOf:) : |
1757+
| nsstring.swift:53:3:53:57 | [summary param] this in copy(with:) : | semmle.label | [summary param] this in copy(with:) : |
1758+
| nsstring.swift:54:3:54:64 | [summary param] this in mutableCopy(with:) : | semmle.label | [summary param] this in mutableCopy(with:) : |
17351759
| nsstring.swift:56:3:56:110 | [summary param] 0 in localizedStringWithFormat(_:_:) : | semmle.label | [summary param] 0 in localizedStringWithFormat(_:_:) : |
17361760
| nsstring.swift:57:3:57:78 | [summary param] 0 in path(withComponents:) : | semmle.label | [summary param] 0 in path(withComponents:) : |
17371761
| nsstring.swift:58:3:58:83 | [summary param] 0 in string(withCString:) : | semmle.label | [summary param] 0 in string(withCString:) : |
@@ -1950,6 +1974,15 @@ nodes
19501974
| nsstring.swift:334:3:334:18 | call to sourceNSString() : | semmle.label | call to sourceNSString() : |
19511975
| nsstring.swift:334:29:334:29 | [post] ptr3 : | semmle.label | [post] ptr3 : |
19521976
| nsstring.swift:335:13:335:13 | ptr3 | semmle.label | ptr3 |
1977+
| nsstring.swift:383:15:383:30 | call to sourceNSString() : | semmle.label | call to sourceNSString() : |
1978+
| nsstring.swift:385:13:385:13 | str20 : | semmle.label | str20 : |
1979+
| nsstring.swift:385:13:385:24 | call to copy() | semmle.label | call to copy() |
1980+
| nsstring.swift:386:13:386:13 | str20 : | semmle.label | str20 : |
1981+
| nsstring.swift:386:13:386:31 | call to mutableCopy() | semmle.label | call to mutableCopy() |
1982+
| nsstring.swift:387:13:387:13 | str20 : | semmle.label | str20 : |
1983+
| nsstring.swift:387:13:387:33 | call to copy(with:) | semmle.label | call to copy(with:) |
1984+
| nsstring.swift:388:13:388:13 | str20 : | semmle.label | str20 : |
1985+
| nsstring.swift:388:13:388:40 | call to mutableCopy(with:) | semmle.label | call to mutableCopy(with:) |
19531986
| nsstring.swift:392:13:392:35 | call to sourceNSMutableString() : | semmle.label | call to sourceNSMutableString() : |
19541987
| nsstring.swift:392:13:392:58 | call to capitalized(with:) | semmle.label | call to capitalized(with:) |
19551988
| nsstring.swift:396:3:396:3 | [post] str30 : | semmle.label | [post] str30 : |
@@ -2616,6 +2649,10 @@ subpaths
26162649
| nsstring.swift:311:13:311:28 | call to sourceNSString() : | nsstring.swift:95:3:95:74 | [summary param] this in strings(byAppendingPaths:) : | file://:0:0:0:0 | [summary] to write: return (return) in strings(byAppendingPaths:) : | nsstring.swift:311:13:311:60 | call to strings(byAppendingPaths:) |
26172650
| nsstring.swift:312:13:312:28 | call to sourceNSString() : | nsstring.swift:95:3:95:74 | [summary param] this in strings(byAppendingPaths:) : | file://:0:0:0:0 | [summary] to write: return (return) in strings(byAppendingPaths:) : | nsstring.swift:312:13:312:60 | call to strings(byAppendingPaths:) : |
26182651
| nsstring.swift:334:3:334:18 | call to sourceNSString() : | nsstring.swift:66:3:66:281 | [summary param] this in getBytes(_:maxLength:usedLength:encoding:options:range:remaining:) : | file://:0:0:0:0 | [summary] to write: argument 0 in getBytes(_:maxLength:usedLength:encoding:options:range:remaining:) : | nsstring.swift:334:29:334:29 | [post] ptr3 : |
2652+
| nsstring.swift:385:13:385:13 | str20 : | nsstring.swift:7:3:7:33 | [summary param] this in copy() : | file://:0:0:0:0 | [summary] to write: return (return) in copy() : | nsstring.swift:385:13:385:24 | call to copy() |
2653+
| nsstring.swift:386:13:386:13 | str20 : | nsstring.swift:8:3:8:40 | [summary param] this in mutableCopy() : | file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy() : | nsstring.swift:386:13:386:31 | call to mutableCopy() |
2654+
| nsstring.swift:387:13:387:13 | str20 : | nsstring.swift:53:3:53:57 | [summary param] this in copy(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in copy(with:) : | nsstring.swift:387:13:387:33 | call to copy(with:) |
2655+
| nsstring.swift:388:13:388:13 | str20 : | nsstring.swift:54:3:54:64 | [summary param] this in mutableCopy(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in mutableCopy(with:) : | nsstring.swift:388:13:388:40 | call to mutableCopy(with:) |
26192656
| nsstring.swift:392:13:392:35 | call to sourceNSMutableString() : | nsstring.swift:77:3:77:64 | [summary param] this in capitalized(with:) : | file://:0:0:0:0 | [summary] to write: return (return) in capitalized(with:) : | nsstring.swift:392:13:392:58 | call to capitalized(with:) |
26202657
| nsstring.swift:396:16:396:29 | call to sourceString() : | nsstring.swift:131:3:131:35 | [summary param] 0 in append(_:) : | file://:0:0:0:0 | [summary] to write: argument this in append(_:) : | nsstring.swift:396:3:396:3 | [post] str30 : |
26212658
| nsstring.swift:401:16:401:29 | call to sourceString() : | nsstring.swift:132:3:132:48 | [summary param] 0 in insert(_:at:) : | file://:0:0:0:0 | [summary] to write: argument this in insert(_:at:) : | nsstring.swift:401:3:401:3 | [post] str31 : |
@@ -2888,6 +2925,10 @@ subpaths
28882925
| nsstring.swift:311:13:311:60 | call to strings(byAppendingPaths:) | nsstring.swift:311:13:311:28 | call to sourceNSString() : | nsstring.swift:311:13:311:60 | call to strings(byAppendingPaths:) | result |
28892926
| nsstring.swift:312:13:312:63 | ...[...] | nsstring.swift:312:13:312:28 | call to sourceNSString() : | nsstring.swift:312:13:312:63 | ...[...] | result |
28902927
| nsstring.swift:335:13:335:13 | ptr3 | nsstring.swift:334:3:334:18 | call to sourceNSString() : | nsstring.swift:335:13:335:13 | ptr3 | result |
2928+
| nsstring.swift:385:13:385:24 | call to copy() | nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:385:13:385:24 | call to copy() | result |
2929+
| nsstring.swift:386:13:386:31 | call to mutableCopy() | nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:386:13:386:31 | call to mutableCopy() | result |
2930+
| nsstring.swift:387:13:387:33 | call to copy(with:) | nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:387:13:387:33 | call to copy(with:) | result |
2931+
| nsstring.swift:388:13:388:40 | call to mutableCopy(with:) | nsstring.swift:383:15:383:30 | call to sourceNSString() : | nsstring.swift:388:13:388:40 | call to mutableCopy(with:) | result |
28912932
| nsstring.swift:392:13:392:58 | call to capitalized(with:) | nsstring.swift:392:13:392:35 | call to sourceNSMutableString() : | nsstring.swift:392:13:392:58 | call to capitalized(with:) | result |
28922933
| nsstring.swift:397:13:397:13 | str30 | nsstring.swift:396:16:396:29 | call to sourceString() : | nsstring.swift:397:13:397:13 | str30 | result |
28932934
| nsstring.swift:402:13:402:13 | str31 | nsstring.swift:401:16:401:29 | call to sourceString() : | nsstring.swift:402:13:402:13 | str31 | result |

swift/ql/test/library-tests/dataflow/taint/nsstring.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,10 @@ func taintThroughInterpolatedStrings() {
382382

383383
var str20 = sourceNSString()
384384

385-
sink(arg: str20.copy()) // $ MISSING: tainted=
386-
sink(arg: str20.mutableCopy()) // $ MISSING: tainted=
387-
sink(arg: str20.copy(with: nil)) // $ MISSING: tainted=
388-
sink(arg: str20.mutableCopy(with: nil)) // $ MISSING: tainted=
385+
sink(arg: str20.copy()) // $ tainted=383
386+
sink(arg: str20.mutableCopy()) // $ tainted=383
387+
sink(arg: str20.copy(with: nil)) // $ tainted=383
388+
sink(arg: str20.mutableCopy(with: nil)) // $ tainted=383
389389

390390
// `NSMutableString` methods
391391

0 commit comments

Comments
 (0)