Skip to content

Commit c462e01

Browse files
authored
Merge pull request github#12266 from geoffw0/taintplusequals
Swift: Taint through arithmetic
2 parents a5bb336 + 9b117fe commit c462e01

File tree

4 files changed

+196
-6
lines changed

4 files changed

+196
-6
lines changed

swift/ql/lib/codeql/swift/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,8 @@ private module Cached {
4343
nodeFrom.asExpr() = interpolated.getAppendingExpr()
4444
)
4545
or
46-
// allow flow through string concatenation.
47-
exists(AddExpr ae |
48-
ae.getAnOperand() = nodeFrom.asExpr() and
49-
ae = nodeTo.asExpr() and
50-
ae.getType().getName() = "String"
51-
)
46+
// allow flow through arithmetic (this case includes string concatenation)
47+
nodeTo.asExpr().(ArithmeticOperation).getAnOperand() = nodeFrom.asExpr()
5248
or
5349
// flow through a subscript access
5450
exists(SubscriptExpr se |

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

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,86 @@
557557
| nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) | nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 |
558558
| nsmutabledata.swift:48:33:48:40 | call to source() | nsmutabledata.swift:48:9:48:9 | SSA def(nsMutableDataTainted6) |
559559
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 | nsmutabledata.swift:49:15:49:37 | .mutableBytes |
560+
| simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... |
561+
| simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... |
562+
| simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... |
563+
| simple.swift:13:24:13:24 | 1 | simple.swift:13:13:13:24 | ... .+(_:_:) ... |
564+
| simple.swift:14:13:14:13 | 1 | simple.swift:14:13:14:24 | ... .-(_:_:) ... |
565+
| simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... |
566+
| simple.swift:15:13:15:20 | call to source() | simple.swift:15:13:15:24 | ... .-(_:_:) ... |
567+
| simple.swift:15:24:15:24 | 1 | simple.swift:15:13:15:24 | ... .-(_:_:) ... |
568+
| simple.swift:16:13:16:13 | 2 | simple.swift:16:13:16:24 | ... .*(_:_:) ... |
569+
| simple.swift:16:17:16:24 | call to source() | simple.swift:16:13:16:24 | ... .*(_:_:) ... |
570+
| simple.swift:17:13:17:20 | call to source() | simple.swift:17:13:17:24 | ... .*(_:_:) ... |
571+
| simple.swift:17:24:17:24 | 2 | simple.swift:17:13:17:24 | ... .*(_:_:) ... |
572+
| simple.swift:18:13:18:13 | 100 | simple.swift:18:13:18:26 | ... ./(_:_:) ... |
573+
| simple.swift:18:19:18:26 | call to source() | simple.swift:18:13:18:26 | ... ./(_:_:) ... |
574+
| simple.swift:19:13:19:20 | call to source() | simple.swift:19:13:19:24 | ... ./(_:_:) ... |
575+
| simple.swift:19:24:19:24 | 100 | simple.swift:19:13:19:24 | ... ./(_:_:) ... |
576+
| simple.swift:20:13:20:13 | 100 | simple.swift:20:13:20:26 | ... .%(_:_:) ... |
577+
| simple.swift:20:19:20:26 | call to source() | simple.swift:20:13:20:26 | ... .%(_:_:) ... |
578+
| simple.swift:21:13:21:20 | call to source() | simple.swift:21:13:21:24 | ... .%(_:_:) ... |
579+
| simple.swift:21:24:21:24 | 100 | simple.swift:21:13:21:24 | ... .%(_:_:) ... |
580+
| simple.swift:23:14:23:21 | call to source() | simple.swift:23:13:23:21 | call to -(_:) |
581+
| simple.swift:36:7:36:7 | SSA def(a) | simple.swift:37:13:37:13 | a |
582+
| simple.swift:36:11:36:11 | 0 | simple.swift:36:7:36:7 | SSA def(a) |
583+
| simple.swift:37:13:37:13 | [post] a | simple.swift:38:3:38:3 | a |
584+
| simple.swift:37:13:37:13 | a | simple.swift:38:3:38:3 | a |
585+
| simple.swift:38:3:38:3 | &... | simple.swift:39:13:39:13 | a |
586+
| simple.swift:38:3:38:3 | [post] &... | simple.swift:39:13:39:13 | a |
587+
| simple.swift:38:3:38:3 | a | simple.swift:38:3:38:3 | &... |
588+
| simple.swift:39:13:39:13 | [post] a | simple.swift:40:3:40:3 | a |
589+
| simple.swift:39:13:39:13 | a | simple.swift:40:3:40:3 | a |
590+
| simple.swift:40:3:40:3 | &... | simple.swift:41:13:41:13 | a |
591+
| simple.swift:40:3:40:3 | [post] &... | simple.swift:41:13:41:13 | a |
592+
| simple.swift:40:3:40:3 | a | simple.swift:40:3:40:3 | &... |
593+
| simple.swift:41:13:41:13 | [post] a | simple.swift:42:3:42:3 | a |
594+
| simple.swift:41:13:41:13 | a | simple.swift:42:3:42:3 | a |
595+
| simple.swift:42:3:42:3 | &... | simple.swift:43:13:43:13 | a |
596+
| simple.swift:42:3:42:3 | [post] &... | simple.swift:43:13:43:13 | a |
597+
| simple.swift:42:3:42:3 | a | simple.swift:42:3:42:3 | &... |
598+
| simple.swift:44:3:44:7 | SSA def(a) | simple.swift:45:13:45:13 | a |
599+
| simple.swift:44:7:44:7 | 0 | simple.swift:44:3:44:7 | SSA def(a) |
600+
| simple.swift:47:7:47:7 | SSA def(b) | simple.swift:48:3:48:3 | b |
601+
| simple.swift:47:11:47:11 | 128 | simple.swift:47:7:47:7 | SSA def(b) |
602+
| simple.swift:48:3:48:3 | &... | simple.swift:49:13:49:13 | b |
603+
| simple.swift:48:3:48:3 | [post] &... | simple.swift:49:13:49:13 | b |
604+
| simple.swift:48:3:48:3 | b | simple.swift:48:3:48:3 | &... |
605+
| simple.swift:49:13:49:13 | [post] b | simple.swift:50:3:50:3 | b |
606+
| simple.swift:49:13:49:13 | b | simple.swift:50:3:50:3 | b |
607+
| simple.swift:50:3:50:3 | &... | simple.swift:51:13:51:13 | b |
608+
| simple.swift:50:3:50:3 | [post] &... | simple.swift:51:13:51:13 | b |
609+
| simple.swift:50:3:50:3 | b | simple.swift:50:3:50:3 | &... |
610+
| simple.swift:53:7:53:7 | SSA def(c) | simple.swift:54:3:54:3 | c |
611+
| simple.swift:53:11:53:11 | 10 | simple.swift:53:7:53:7 | SSA def(c) |
612+
| simple.swift:54:3:54:3 | &... | simple.swift:55:13:55:13 | c |
613+
| simple.swift:54:3:54:3 | [post] &... | simple.swift:55:13:55:13 | c |
614+
| simple.swift:54:3:54:3 | c | simple.swift:54:3:54:3 | &... |
615+
| simple.swift:55:13:55:13 | [post] c | simple.swift:56:3:56:3 | c |
616+
| simple.swift:55:13:55:13 | c | simple.swift:56:3:56:3 | c |
617+
| simple.swift:56:3:56:3 | &... | simple.swift:57:13:57:13 | c |
618+
| simple.swift:56:3:56:3 | [post] &... | simple.swift:57:13:57:13 | c |
619+
| simple.swift:56:3:56:3 | c | simple.swift:56:3:56:3 | &... |
620+
| simple.swift:59:7:59:7 | SSA def(d) | simple.swift:60:3:60:3 | d |
621+
| simple.swift:59:11:59:11 | 100 | simple.swift:59:7:59:7 | SSA def(d) |
622+
| simple.swift:60:3:60:3 | &... | simple.swift:61:13:61:13 | d |
623+
| simple.swift:60:3:60:3 | [post] &... | simple.swift:61:13:61:13 | d |
624+
| simple.swift:60:3:60:3 | d | simple.swift:60:3:60:3 | &... |
625+
| simple.swift:61:13:61:13 | [post] d | simple.swift:62:3:62:3 | d |
626+
| simple.swift:61:13:61:13 | d | simple.swift:62:3:62:3 | d |
627+
| simple.swift:62:3:62:3 | &... | simple.swift:63:13:63:13 | d |
628+
| simple.swift:62:3:62:3 | [post] &... | simple.swift:63:13:63:13 | d |
629+
| simple.swift:62:3:62:3 | d | simple.swift:62:3:62:3 | &... |
630+
| simple.swift:65:7:65:7 | SSA def(e) | simple.swift:66:3:66:3 | e |
631+
| simple.swift:65:11:65:11 | 1000 | simple.swift:65:7:65:7 | SSA def(e) |
632+
| simple.swift:66:3:66:3 | &... | simple.swift:67:13:67:13 | e |
633+
| simple.swift:66:3:66:3 | [post] &... | simple.swift:67:13:67:13 | e |
634+
| simple.swift:66:3:66:3 | e | simple.swift:66:3:66:3 | &... |
635+
| simple.swift:67:13:67:13 | [post] e | simple.swift:68:3:68:3 | e |
636+
| simple.swift:67:13:67:13 | e | simple.swift:68:3:68:3 | e |
637+
| simple.swift:68:3:68:3 | &... | simple.swift:69:13:69:13 | e |
638+
| simple.swift:68:3:68:3 | [post] &... | simple.swift:69:13:69:13 | e |
639+
| simple.swift:68:3:68:3 | e | simple.swift:68:3:68:3 | &... |
560640
| string.swift:6:8:6:8 | SSA def(self) | string.swift:6:8:6:8 | self[return] |
561641
| string.swift:6:8:6:8 | self | string.swift:6:8:6:8 | SSA def(self) |
562642
| string.swift:10:3:10:3 | SSA def(self) | string.swift:10:3:10:27 | self[return] |

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,17 @@ 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+
| simple.swift:12:17:12:24 | call to source() : | simple.swift:12:13:12:24 | ... .+(_:_:) ... |
335+
| simple.swift:13:13:13:20 | call to source() : | simple.swift:13:13:13:24 | ... .+(_:_:) ... |
336+
| simple.swift:14:17:14:24 | call to source() : | simple.swift:14:13:14:24 | ... .-(_:_:) ... |
337+
| simple.swift:15:13:15:20 | call to source() : | simple.swift:15:13:15:24 | ... .-(_:_:) ... |
338+
| simple.swift:16:17:16:24 | call to source() : | simple.swift:16:13:16:24 | ... .*(_:_:) ... |
339+
| simple.swift:17:13:17:20 | call to source() : | simple.swift:17:13:17:24 | ... .*(_:_:) ... |
340+
| simple.swift:18:19:18:26 | call to source() : | simple.swift:18:13:18:26 | ... ./(_:_:) ... |
341+
| simple.swift:19:13:19:20 | call to source() : | simple.swift:19:13:19:24 | ... ./(_:_:) ... |
342+
| simple.swift:20:19:20:26 | call to source() : | simple.swift:20:13:20:26 | ... .%(_:_:) ... |
343+
| simple.swift:21:13:21:20 | call to source() : | simple.swift:21:13:21:24 | ... .%(_:_:) ... |
344+
| simple.swift:23:14:23:21 | call to source() : | simple.swift:23:13:23:21 | call to -(_:) |
334345
| string.swift:60:2:60:54 | [summary param] 0 in String.init(data:encoding:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(data:encoding:) : |
335346
| string.swift:64:3:64:63 | [summary param] 0 in String.init(format:_:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(format:_:) : |
336347
| string.swift:65:3:65:60 | [summary param] 0 in String.init(format:arguments:) : | file://:0:0:0:0 | [summary] to write: return (return) in String.init(format:arguments:) : |
@@ -1370,6 +1381,28 @@ nodes
13701381
| nsmutabledata.swift:48:33:48:40 | call to source() : | semmle.label | call to source() : |
13711382
| nsmutabledata.swift:49:15:49:15 | nsMutableDataTainted6 : | semmle.label | nsMutableDataTainted6 : |
13721383
| nsmutabledata.swift:49:15:49:37 | .mutableBytes | semmle.label | .mutableBytes |
1384+
| simple.swift:12:13:12:24 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
1385+
| simple.swift:12:17:12:24 | call to source() : | semmle.label | call to source() : |
1386+
| simple.swift:13:13:13:20 | call to source() : | semmle.label | call to source() : |
1387+
| simple.swift:13:13:13:24 | ... .+(_:_:) ... | semmle.label | ... .+(_:_:) ... |
1388+
| simple.swift:14:13:14:24 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
1389+
| simple.swift:14:17:14:24 | call to source() : | semmle.label | call to source() : |
1390+
| simple.swift:15:13:15:20 | call to source() : | semmle.label | call to source() : |
1391+
| simple.swift:15:13:15:24 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
1392+
| simple.swift:16:13:16:24 | ... .*(_:_:) ... | semmle.label | ... .*(_:_:) ... |
1393+
| simple.swift:16:17:16:24 | call to source() : | semmle.label | call to source() : |
1394+
| simple.swift:17:13:17:20 | call to source() : | semmle.label | call to source() : |
1395+
| simple.swift:17:13:17:24 | ... .*(_:_:) ... | semmle.label | ... .*(_:_:) ... |
1396+
| simple.swift:18:13:18:26 | ... ./(_:_:) ... | semmle.label | ... ./(_:_:) ... |
1397+
| simple.swift:18:19:18:26 | call to source() : | semmle.label | call to source() : |
1398+
| simple.swift:19:13:19:20 | call to source() : | semmle.label | call to source() : |
1399+
| simple.swift:19:13:19:24 | ... ./(_:_:) ... | semmle.label | ... ./(_:_:) ... |
1400+
| simple.swift:20:13:20:26 | ... .%(_:_:) ... | semmle.label | ... .%(_:_:) ... |
1401+
| simple.swift:20:19:20:26 | call to source() : | semmle.label | call to source() : |
1402+
| simple.swift:21:13:21:20 | call to source() : | semmle.label | call to source() : |
1403+
| simple.swift:21:13:21:24 | ... .%(_:_:) ... | semmle.label | ... .%(_:_:) ... |
1404+
| simple.swift:23:13:23:21 | call to -(_:) | semmle.label | call to -(_:) |
1405+
| simple.swift:23:14:23:21 | call to source() : | semmle.label | call to source() : |
13731406
| string.swift:60:2:60:54 | [summary param] 0 in String.init(data:encoding:) : | semmle.label | [summary param] 0 in String.init(data:encoding:) : |
13741407
| string.swift:64:3:64:63 | [summary param] 0 in String.init(format:_:) : | semmle.label | [summary param] 0 in String.init(format:_:) : |
13751408
| string.swift:65:3:65:60 | [summary param] 0 in String.init(format:arguments:) : | semmle.label | [summary param] 0 in String.init(format:arguments:) : |
@@ -2084,6 +2117,17 @@ subpaths
20842117
| nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | nsmutabledata.swift:40:66:40:73 | call to source() : | nsmutabledata.swift:41:15:41:15 | nsMutableDataTainted4 | result |
20852118
| nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | nsmutabledata.swift:44:35:44:42 | call to source() : | nsmutabledata.swift:45:15:45:15 | nsMutableDataTainted5 | result |
20862119
| nsmutabledata.swift:49:15:49:37 | .mutableBytes | nsmutabledata.swift:48:33:48:40 | call to source() : | nsmutabledata.swift:49:15:49:37 | .mutableBytes | result |
2120+
| simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() : | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result |
2121+
| simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() : | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result |
2122+
| simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() : | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result |
2123+
| simple.swift:15:13:15:24 | ... .-(_:_:) ... | simple.swift:15:13:15:20 | call to source() : | simple.swift:15:13:15:24 | ... .-(_:_:) ... | result |
2124+
| simple.swift:16:13:16:24 | ... .*(_:_:) ... | simple.swift:16:17:16:24 | call to source() : | simple.swift:16:13:16:24 | ... .*(_:_:) ... | result |
2125+
| simple.swift:17:13:17:24 | ... .*(_:_:) ... | simple.swift:17:13:17:20 | call to source() : | simple.swift:17:13:17:24 | ... .*(_:_:) ... | result |
2126+
| simple.swift:18:13:18:26 | ... ./(_:_:) ... | simple.swift:18:19:18:26 | call to source() : | simple.swift:18:13:18:26 | ... ./(_:_:) ... | result |
2127+
| simple.swift:19:13:19:24 | ... ./(_:_:) ... | simple.swift:19:13:19:20 | call to source() : | simple.swift:19:13:19:24 | ... ./(_:_:) ... | result |
2128+
| simple.swift:20:13:20:26 | ... .%(_:_:) ... | simple.swift:20:19:20:26 | call to source() : | simple.swift:20:13:20:26 | ... .%(_:_:) ... | result |
2129+
| simple.swift:21:13:21:24 | ... .%(_:_:) ... | simple.swift:21:13:21:20 | call to source() : | simple.swift:21:13:21:24 | ... .%(_:_:) ... | result |
2130+
| simple.swift:23:13:23:21 | call to -(_:) | simple.swift:23:14:23:21 | call to source() : | simple.swift:23:13:23:21 | call to -(_:) | result |
20872131
| string.swift:139:13:139:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:139:13:139:13 | "..." | result |
20882132
| string.swift:141:13:141:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:141:13:141:13 | "..." | result |
20892133
| string.swift:143:13:143:13 | "..." | string.swift:137:11:137:18 | call to source() : | string.swift:143:13:143:13 | "..." | result |
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
// --- stubs ---
3+
4+
// --- tests ---
5+
6+
func source() -> Int { return 0; }
7+
func sink(arg: Any) {}
8+
9+
func taintThroughArithmetic() {
10+
// arithmetic
11+
12+
sink(arg: 1 + source()) // $ tainted=12
13+
sink(arg: source() + 1) // $ tainted=13
14+
sink(arg: 1 - source()) // $ tainted=14
15+
sink(arg: source() - 1) // $ tainted=15
16+
sink(arg: 2 * source()) // $ tainted=16
17+
sink(arg: source() * 2) // $ tainted=17
18+
sink(arg: 100 / source()) // $ tainted=18
19+
sink(arg: source() / 100) // $ tainted=19
20+
sink(arg: 100 % source()) // $ tainted=20
21+
sink(arg: source() % 100) // $ tainted=21
22+
23+
sink(arg: -source()) // $ tainted=23
24+
25+
// overflow operators
26+
27+
sink(arg: 1 &+ source()) // $ MISSING: tainted=
28+
sink(arg: source() &+ 1) // $ MISSING: tainted=
29+
sink(arg: 1 &- source()) // $ MISSING: tainted=
30+
sink(arg: source() &- 1) // $ MISSING: tainted=
31+
sink(arg: 2 &* source()) // $ MISSING: tainted=
32+
sink(arg: source() &* 2) // $ MISSING: tainted=
33+
}
34+
35+
func taintThroughAssignmentArithmetic() {
36+
var a = 0
37+
sink(arg: a)
38+
a += 1
39+
sink(arg: a)
40+
a += source()
41+
sink(arg: a) // $ MISSING: tainted=
42+
a += 1
43+
sink(arg: a) // $ MISSING: tainted=
44+
a = 0
45+
sink(arg: a)
46+
47+
var b = 128
48+
b -= source()
49+
sink(arg: b) // $ MISSING: tainted=
50+
b -= 1
51+
sink(arg: b) // $ MISSING: tainted=
52+
53+
var c = 10
54+
c *= source()
55+
sink(arg: c) // $ MISSING: tainted=
56+
c *= 2
57+
sink(arg: c) // $ MISSING: tainted=
58+
59+
var d = 100
60+
d /= source()
61+
sink(arg: d) // $ MISSING: tainted=
62+
d /= 2
63+
sink(arg: d) // $ MISSING: tainted=
64+
65+
var e = 1000
66+
e %= source()
67+
sink(arg: e) // $ MISSING: tainted=
68+
e %= 100
69+
sink(arg: e) // $ MISSING: tainted=
70+
}

0 commit comments

Comments
 (0)