Skip to content

Commit 11e0efe

Browse files
authored
Merge pull request github#12308 from geoffw0/taintplusequals2
Swift: Model assignment operators (+= etc)
2 parents aa6c60a + bb55456 commit 11e0efe

File tree

9 files changed

+422
-11
lines changed

9 files changed

+422
-11
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ private module Cached {
4646
// allow flow through arithmetic (this case includes string concatenation)
4747
nodeTo.asExpr().(ArithmeticOperation).getAnOperand() = nodeFrom.asExpr()
4848
or
49+
// allow flow through assignment operations (e.g. `+=`)
50+
exists(AssignOperation op |
51+
nodeFrom.asExpr() = op.getSource() and
52+
nodeTo.asExpr() = op.getDest()
53+
)
54+
or
4955
// flow through a subscript access
5056
exists(SubscriptExpr se |
5157
se.getBase() = nodeFrom.asExpr() and
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,254 @@
11
private import codeql.swift.generated.expr.AssignExpr
2+
private import codeql.swift.elements.expr.BinaryExpr
23

4+
/**
5+
* An assignment expression. For example:
6+
* ```
7+
* x = 0
8+
* y += 1
9+
* z <<= 1
10+
* ```
11+
*/
12+
class Assignment extends Expr {
13+
Assignment() {
14+
this instanceof AssignExpr or
15+
this instanceof AssignArithmeticOperationEx or
16+
this instanceof AssignBitwiseOperationEx or
17+
this instanceof AssignPointwiseOperationEx
18+
}
19+
20+
/**
21+
* Gets the destination of this assignment. For example `x` in:
22+
* ```
23+
* x = y
24+
* ```
25+
*/
26+
Expr getDest() {
27+
result = this.(AssignExpr).getDest() or
28+
result = this.(AssignOperation).getLeftOperand()
29+
}
30+
31+
/**
32+
* Gets the source of this assignment. For example `y` in:
33+
* ```
34+
* x = y
35+
* ```
36+
*/
37+
Expr getSource() {
38+
result = this.(AssignExpr).getSource() or
39+
result = this.(AssignOperation).getRightOperand()
40+
}
41+
42+
/**
43+
* Holds if this assignment expression uses an overflow operator, that is,
44+
* an operator that truncates overflow rather than reporting an error.
45+
* ```
46+
* x &+= y
47+
* ```
48+
*/
49+
predicate hasOverflowOperator() {
50+
this.(AssignOperation).getOperator().getName() =
51+
["&*=(_:_:)", "&+=(_:_:)", "&-=(_:_:)", "&<<=(_:_:)", "&>>=(_:_:)"]
52+
}
53+
}
54+
55+
/**
56+
* A simple assignment expression using the `=` operator:
57+
* ```
58+
* x = 0
59+
* ```
60+
*/
361
class AssignExpr extends Generated::AssignExpr {
462
override string toString() { result = " ... = ..." }
563
}
64+
65+
/**
66+
* An assignment expression apart from `=`. For example:
67+
* ```
68+
* x += 1
69+
* y &= z
70+
* ```
71+
*/
72+
class AssignOperation extends Assignment, BinaryExpr {
73+
AssignOperation() {
74+
this instanceof AssignArithmeticOperationEx or
75+
this instanceof AssignBitwiseOperationEx or
76+
this instanceof AssignPointwiseOperationEx
77+
}
78+
}
79+
80+
/**
81+
* An arithmetic assignment expression. For example:
82+
* ```
83+
* x += 1
84+
* y *= z
85+
* ```
86+
*/
87+
class AssignArithmeticOperation extends AssignOperation instanceof AssignArithmeticOperationEx { }
88+
89+
/**
90+
* Private abstract class, extended to define the scope of `AssignArithmeticOperation`.
91+
*/
92+
abstract private class AssignArithmeticOperationEx extends BinaryExpr { }
93+
94+
/**
95+
* A bitwise assignment expression. For example:
96+
* ```
97+
* x &= y
98+
* z <<= 1
99+
* ```
100+
*/
101+
class AssignBitwiseOperation extends AssignOperation instanceof AssignBitwiseOperationEx { }
102+
103+
/**
104+
* Private abstract class, extended to define the scope of `AssignBitwiseOperation`.
105+
*/
106+
abstract private class AssignBitwiseOperationEx extends BinaryExpr { }
107+
108+
/**
109+
* A pointwise assignment expression. For example:
110+
* ```
111+
* x .&= y
112+
* ```
113+
*/
114+
class AssignPointwiseOperation extends AssignOperation instanceof AssignPointwiseOperationEx { }
115+
116+
/**
117+
* Private abstract class, extended to define the scope of `AssignPointwiseOperation`.
118+
*/
119+
abstract private class AssignPointwiseOperationEx extends BinaryExpr { }
120+
121+
/**
122+
* An addition assignment expression:
123+
* ```
124+
* a += b
125+
* a &+= b
126+
* ```
127+
*/
128+
class AssignAddExpr extends AssignArithmeticOperationEx {
129+
AssignAddExpr() { this.getOperator().getName() = ["+=(_:_:)", "&+=(_:_:)"] }
130+
}
131+
132+
/**
133+
* A subtraction assignment expression:
134+
* ```
135+
* a -= b
136+
* a &-= b
137+
* ```
138+
*/
139+
class AssignSubExpr extends AssignArithmeticOperationEx {
140+
AssignSubExpr() { this.getOperator().getName() = ["-=(_:_:)", "&-=(_:_:)"] }
141+
}
142+
143+
/**
144+
* A multiplication assignment expression:
145+
* ```
146+
* a *= b
147+
* a &*= b
148+
* ```
149+
*/
150+
class AssignMulExpr extends AssignArithmeticOperationEx {
151+
AssignMulExpr() { this.getOperator().getName() = ["*=(_:_:)", "&*=(_:_:)"] }
152+
}
153+
154+
/**
155+
* A division assignment expression:
156+
* ```
157+
* a /= b
158+
* ```
159+
*/
160+
class AssignDivExpr extends AssignArithmeticOperationEx {
161+
AssignDivExpr() { this.getOperator().getName() = "/=(_:_:)" }
162+
}
163+
164+
/**
165+
* A remainder assignment expression:
166+
* ```
167+
* a %= b
168+
* ```
169+
*/
170+
class AssignRemExpr extends AssignArithmeticOperationEx {
171+
AssignRemExpr() { this.getOperator().getName() = "%=(_:_:)" }
172+
}
173+
174+
/**
175+
* A left-shift assignment expression:
176+
* ```
177+
* a <<= b
178+
* a &<<= b
179+
* ```
180+
*/
181+
class AssignLShiftExpr extends AssignBitwiseOperationEx {
182+
AssignLShiftExpr() { this.getOperator().getName() = ["<<=(_:_:)", "&<<=(_:_:)"] }
183+
}
184+
185+
/**
186+
* A right-shift assignment expression:
187+
* ```
188+
* a >>= b
189+
* a &>>= b
190+
* ```
191+
*/
192+
class AssignRShiftExpr extends AssignBitwiseOperationEx {
193+
AssignRShiftExpr() { this.getOperator().getName() = [">>=(_:_:)", "&>>=(_:_:)"] }
194+
}
195+
196+
/**
197+
* A bitwise-and assignment expression:
198+
* ```
199+
* a &= b
200+
* ```
201+
*/
202+
class AssignAndExpr extends AssignBitwiseOperationEx {
203+
AssignAndExpr() { this.getOperator().getName() = "&=(_:_:)" }
204+
}
205+
206+
/**
207+
* A bitwise-or assignment expression:
208+
* ```
209+
* a |= b
210+
* ```
211+
*/
212+
class AssignOrExpr extends AssignBitwiseOperationEx {
213+
AssignOrExpr() { this.getOperator().getName() = "|=(_:_:)" }
214+
}
215+
216+
/**
217+
* A bitwise exclusive-or assignment expression:
218+
* ```
219+
* a ^= b
220+
* ```
221+
*/
222+
class AssignXorExpr extends AssignBitwiseOperationEx {
223+
AssignXorExpr() { this.getOperator().getName() = "^=(_:_:)" }
224+
}
225+
226+
/**
227+
* A pointwise bitwise-and assignment expression:
228+
* ```
229+
* a .&= b
230+
* ```
231+
*/
232+
class AssignPointwiseAndExpr extends AssignPointwiseOperationEx {
233+
AssignPointwiseAndExpr() { this.getOperator().getName() = ".&=(_:_:)" }
234+
}
235+
236+
/**
237+
* A pointwise bitwise-or assignment expression:
238+
* ```
239+
* a .|= b
240+
* ```
241+
*/
242+
class AssignPointwiseOrExpr extends AssignPointwiseOperationEx {
243+
AssignPointwiseOrExpr() { this.getOperator().getName() = ".|=(_:_:)" }
244+
}
245+
246+
/**
247+
* A pointwise bitwise exclusive-or assignment expression:
248+
* ```
249+
* a .^= b
250+
* ```
251+
*/
252+
class AssignPointwiseXorExpr extends AssignPointwiseOperationEx {
253+
AssignPointwiseXorExpr() { this.getOperator().getName() = ".^=(_:_:)" }
254+
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
| data.swift:195:58:195:58 | &... | data.swift:195:58:195:73 | ...[...] |
254254
| data.swift:195:58:195:58 | c | data.swift:195:58:195:58 | &... |
255255
| data.swift:195:58:195:73 | ...[...] | data.swift:195:58:195:73 | &... |
256+
| data.swift:195:78:195:78 | 1 | data.swift:195:58:195:73 | &... |
256257
| data.swift:199:6:199:6 | SSA def(dataTainted27) | data.swift:200:2:200:2 | dataTainted27 |
257258
| data.swift:199:22:199:29 | call to Data.init(_:) | data.swift:199:6:199:6 | SSA def(dataTainted27) |
258259
| data.swift:199:27:199:27 | | data.swift:199:22:199:29 | call to Data.init(_:) |
@@ -585,58 +586,69 @@
585586
| simple.swift:38:3:38:3 | &... | simple.swift:39:13:39:13 | a |
586587
| simple.swift:38:3:38:3 | [post] &... | simple.swift:39:13:39:13 | a |
587588
| simple.swift:38:3:38:3 | a | simple.swift:38:3:38:3 | &... |
589+
| simple.swift:38:8:38:8 | 1 | simple.swift:38:3:38:3 | &... |
588590
| simple.swift:39:13:39:13 | [post] a | simple.swift:40:3:40:3 | a |
589591
| simple.swift:39:13:39:13 | a | simple.swift:40:3:40:3 | a |
590592
| simple.swift:40:3:40:3 | &... | simple.swift:41:13:41:13 | a |
591593
| simple.swift:40:3:40:3 | [post] &... | simple.swift:41:13:41:13 | a |
592594
| simple.swift:40:3:40:3 | a | simple.swift:40:3:40:3 | &... |
595+
| simple.swift:40:8:40:15 | call to source() | simple.swift:40:3:40:3 | &... |
593596
| simple.swift:41:13:41:13 | [post] a | simple.swift:42:3:42:3 | a |
594597
| simple.swift:41:13:41:13 | a | simple.swift:42:3:42:3 | a |
595598
| simple.swift:42:3:42:3 | &... | simple.swift:43:13:43:13 | a |
596599
| simple.swift:42:3:42:3 | [post] &... | simple.swift:43:13:43:13 | a |
597600
| simple.swift:42:3:42:3 | a | simple.swift:42:3:42:3 | &... |
601+
| simple.swift:42:8:42:8 | 1 | simple.swift:42:3:42:3 | &... |
598602
| simple.swift:44:3:44:7 | SSA def(a) | simple.swift:45:13:45:13 | a |
599603
| simple.swift:44:7:44:7 | 0 | simple.swift:44:3:44:7 | SSA def(a) |
600604
| simple.swift:47:7:47:7 | SSA def(b) | simple.swift:48:3:48:3 | b |
601605
| simple.swift:47:11:47:11 | 128 | simple.swift:47:7:47:7 | SSA def(b) |
602606
| simple.swift:48:3:48:3 | &... | simple.swift:49:13:49:13 | b |
603607
| simple.swift:48:3:48:3 | [post] &... | simple.swift:49:13:49:13 | b |
604608
| simple.swift:48:3:48:3 | b | simple.swift:48:3:48:3 | &... |
609+
| simple.swift:48:8:48:15 | call to source() | simple.swift:48:3:48:3 | &... |
605610
| simple.swift:49:13:49:13 | [post] b | simple.swift:50:3:50:3 | b |
606611
| simple.swift:49:13:49:13 | b | simple.swift:50:3:50:3 | b |
607612
| simple.swift:50:3:50:3 | &... | simple.swift:51:13:51:13 | b |
608613
| simple.swift:50:3:50:3 | [post] &... | simple.swift:51:13:51:13 | b |
609614
| simple.swift:50:3:50:3 | b | simple.swift:50:3:50:3 | &... |
615+
| simple.swift:50:8:50:8 | 1 | simple.swift:50:3:50:3 | &... |
610616
| simple.swift:53:7:53:7 | SSA def(c) | simple.swift:54:3:54:3 | c |
611617
| simple.swift:53:11:53:11 | 10 | simple.swift:53:7:53:7 | SSA def(c) |
612618
| simple.swift:54:3:54:3 | &... | simple.swift:55:13:55:13 | c |
613619
| simple.swift:54:3:54:3 | [post] &... | simple.swift:55:13:55:13 | c |
614620
| simple.swift:54:3:54:3 | c | simple.swift:54:3:54:3 | &... |
621+
| simple.swift:54:8:54:15 | call to source() | simple.swift:54:3:54:3 | &... |
615622
| simple.swift:55:13:55:13 | [post] c | simple.swift:56:3:56:3 | c |
616623
| simple.swift:55:13:55:13 | c | simple.swift:56:3:56:3 | c |
617624
| simple.swift:56:3:56:3 | &... | simple.swift:57:13:57:13 | c |
618625
| simple.swift:56:3:56:3 | [post] &... | simple.swift:57:13:57:13 | c |
619626
| simple.swift:56:3:56:3 | c | simple.swift:56:3:56:3 | &... |
627+
| simple.swift:56:8:56:8 | 2 | simple.swift:56:3:56:3 | &... |
620628
| simple.swift:59:7:59:7 | SSA def(d) | simple.swift:60:3:60:3 | d |
621629
| simple.swift:59:11:59:11 | 100 | simple.swift:59:7:59:7 | SSA def(d) |
622630
| simple.swift:60:3:60:3 | &... | simple.swift:61:13:61:13 | d |
623631
| simple.swift:60:3:60:3 | [post] &... | simple.swift:61:13:61:13 | d |
624632
| simple.swift:60:3:60:3 | d | simple.swift:60:3:60:3 | &... |
633+
| simple.swift:60:8:60:15 | call to source() | simple.swift:60:3:60:3 | &... |
625634
| simple.swift:61:13:61:13 | [post] d | simple.swift:62:3:62:3 | d |
626635
| simple.swift:61:13:61:13 | d | simple.swift:62:3:62:3 | d |
627636
| simple.swift:62:3:62:3 | &... | simple.swift:63:13:63:13 | d |
628637
| simple.swift:62:3:62:3 | [post] &... | simple.swift:63:13:63:13 | d |
629638
| simple.swift:62:3:62:3 | d | simple.swift:62:3:62:3 | &... |
639+
| simple.swift:62:8:62:8 | 2 | simple.swift:62:3:62:3 | &... |
630640
| simple.swift:65:7:65:7 | SSA def(e) | simple.swift:66:3:66:3 | e |
631641
| simple.swift:65:11:65:11 | 1000 | simple.swift:65:7:65:7 | SSA def(e) |
632642
| simple.swift:66:3:66:3 | &... | simple.swift:67:13:67:13 | e |
633643
| simple.swift:66:3:66:3 | [post] &... | simple.swift:67:13:67:13 | e |
634644
| simple.swift:66:3:66:3 | e | simple.swift:66:3:66:3 | &... |
645+
| simple.swift:66:8:66:15 | call to source() | simple.swift:66:3:66:3 | &... |
635646
| simple.swift:67:13:67:13 | [post] e | simple.swift:68:3:68:3 | e |
636647
| simple.swift:67:13:67:13 | e | simple.swift:68:3:68:3 | e |
637648
| simple.swift:68:3:68:3 | &... | simple.swift:69:13:69:13 | e |
638649
| simple.swift:68:3:68:3 | [post] &... | simple.swift:69:13:69:13 | e |
639650
| simple.swift:68:3:68:3 | e | simple.swift:68:3:68:3 | &... |
651+
| simple.swift:68:8:68:8 | 100 | simple.swift:68:3:68:3 | &... |
640652
| string.swift:6:8:6:8 | SSA def(self) | string.swift:6:8:6:8 | self[return] |
641653
| string.swift:6:8:6:8 | self | string.swift:6:8:6:8 | SSA def(self) |
642654
| string.swift:10:3:10:3 | SSA def(self) | string.swift:10:3:10:27 | self[return] |
@@ -1166,11 +1178,13 @@
11661178
| string.swift:181:3:181:3 | &... | string.swift:182:13:182:13 | str |
11671179
| string.swift:181:3:181:3 | [post] &... | string.swift:182:13:182:13 | str |
11681180
| string.swift:181:3:181:3 | str | string.swift:181:3:181:3 | &... |
1181+
| string.swift:181:10:181:10 | def | string.swift:181:3:181:3 | &... |
11691182
| string.swift:182:13:182:13 | [post] str | string.swift:183:3:183:3 | str |
11701183
| string.swift:182:13:182:13 | str | string.swift:183:3:183:3 | str |
11711184
| string.swift:183:3:183:3 | &... | string.swift:184:13:184:13 | str |
11721185
| string.swift:183:3:183:3 | [post] &... | string.swift:184:13:184:13 | str |
11731186
| string.swift:183:3:183:3 | str | string.swift:183:3:183:3 | &... |
1187+
| string.swift:183:10:183:18 | call to source2() | string.swift:183:3:183:3 | &... |
11741188
| string.swift:186:7:186:7 | SSA def(str2) | string.swift:187:13:187:13 | str2 |
11751189
| string.swift:186:14:186:14 | abc | string.swift:186:7:186:7 | SSA def(str2) |
11761190
| string.swift:187:13:187:13 | [post] str2 | string.swift:188:3:188:3 | str2 |

0 commit comments

Comments
 (0)