1
1
2
2
// --- stubs ---
3
3
4
- func sourceString( ) -> String { return " " }
5
- func sourceUInt8( ) -> UInt8 { return 0 }
4
+ func sourceInt( _ label: String ) -> Int { return 0 }
5
+ func sourceString( _ label: String ) -> String { return " " }
6
+ func sourceUInt8( _ label: String ) -> UInt8 { return 0 }
6
7
func sink( arg: Any ) { }
7
8
8
9
// --- tests ---
@@ -18,14 +19,14 @@ func taintPointer(ptr: UnsafeMutablePointer<String>) {
18
19
sink ( arg: ptr. pointee)
19
20
sink ( arg: ptr)
20
21
21
- ptr. pointee = sourceString ( )
22
+ ptr. pointee = sourceString ( " taintPointer " )
22
23
23
- sink ( arg: ptr. pointee) // $ tainted=21
24
+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
24
25
sink ( arg: ptr)
25
26
}
26
27
27
28
func clearPointer2( ptr: UnsafeMutablePointer < String > ) {
28
- sink ( arg: ptr. pointee) // $ tainted=21
29
+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
29
30
sink ( arg: ptr)
30
31
31
32
ptr. pointee = " abc "
@@ -42,12 +43,12 @@ func testMutatingPointerInCall(ptr: UnsafeMutablePointer<String>) {
42
43
43
44
taintPointer ( ptr: ptr) // mutates `ptr` pointee with a tainted value
44
45
45
- sink ( arg: ptr. pointee) // $ tainted=21
46
+ sink ( arg: ptr. pointee) // $ tainted=taintPointer
46
47
sink ( arg: ptr)
47
48
48
49
clearPointer2 ( ptr: ptr)
49
50
50
- sink ( arg: ptr. pointee) // $ SPURIOUS: tainted=21
51
+ sink ( arg: ptr. pointee) // $ SPURIOUS: tainted=taintPointer
51
52
sink ( arg: ptr)
52
53
}
53
54
@@ -57,10 +58,10 @@ func taintBuffer(buffer: UnsafeMutableBufferPointer<UInt8>) {
57
58
sink ( arg: buffer [ 0 ] )
58
59
sink ( arg: buffer)
59
60
60
- buffer [ 0 ] = sourceUInt8 ( )
61
+ buffer [ 0 ] = sourceUInt8 ( " taintBuffer " )
61
62
62
- sink ( arg: buffer [ 0 ] ) // $ tainted=60
63
- sink ( arg: buffer) // $ tainted=60
63
+ sink ( arg: buffer [ 0 ] ) // $ tainted=taintBuffer
64
+ sink ( arg: buffer) // $ tainted=taintBuffer
64
65
}
65
66
66
67
func testMutatingBufferInCall( ptr: UnsafeMutablePointer < UInt8 > ) {
@@ -71,8 +72,8 @@ func testMutatingBufferInCall(ptr: UnsafeMutablePointer<UInt8>) {
71
72
72
73
taintBuffer ( buffer: buffer) // mutates `buffer` contents with a tainted value
73
74
74
- sink ( arg: buffer [ 0 ] ) // $ tainted=60
75
- sink ( arg: buffer) // $ tainted=60
75
+ sink ( arg: buffer [ 0 ] ) // $ tainted=taintBuffer
76
+ sink ( arg: buffer) // $ tainted=taintBuffer
76
77
77
78
}
78
79
@@ -84,9 +85,9 @@ func taintMyPointer(ptr: MyPointer) {
84
85
sink ( arg: ptr. pointee)
85
86
sink ( arg: ptr)
86
87
87
- ptr. pointee = sourceString ( )
88
+ ptr. pointee = sourceString ( " taintMyPointer " )
88
89
89
- sink ( arg: ptr. pointee) // $ tainted=87
90
+ sink ( arg: ptr. pointee) // $ tainted=taintMyPointer
90
91
sink ( arg: ptr)
91
92
}
92
93
@@ -96,7 +97,7 @@ func testMutatingMyPointerInCall(ptr: MyPointer) {
96
97
97
98
taintMyPointer ( ptr: ptr) // mutates `ptr` pointee with a tainted value
98
99
99
- sink ( arg: ptr. pointee) // $ MISSING: tainted=87
100
+ sink ( arg: ptr. pointee) // $ MISSING: tainted=taintMyPointer
100
101
sink ( arg: ptr)
101
102
}
102
103
@@ -111,19 +112,94 @@ struct MyGenericPointerContainer<T> {
111
112
}
112
113
113
114
func writePointerContainer( mpc: MyPointerContainer ) {
114
- mpc. ptr. pointee = sourceString ( )
115
- sink ( arg: mpc. ptr. pointee) // $ tainted=114
115
+ mpc. ptr. pointee = sourceString ( " writePointerContainer " )
116
+ sink ( arg: mpc. ptr. pointee) // $ tainted=writePointerContainer
116
117
}
117
118
118
119
func writeGenericPointerContainer< T> ( mgpc: MyGenericPointerContainer < T > ) {
119
- mgpc. ptr. pointee = sourceString ( ) as! T
120
- sink ( arg: mgpc. ptr. pointee) // $ tainted=119
120
+ mgpc. ptr. pointee = sourceString ( " writeGenericPointerContainer " ) as! T
121
+ sink ( arg: mgpc. ptr. pointee) // $ tainted=writeGenericPointerContainer
121
122
}
122
123
123
124
func testWritingPointerContainersInCalls( mpc: MyPointerContainer , mgpc: MyGenericPointerContainer < Int > ) {
124
125
writePointerContainer ( mpc: mpc)
125
- sink ( arg: mpc. ptr. pointee) // $ tainted=114
126
+ sink ( arg: mpc. ptr. pointee) // $ tainted=writePointerContainer
126
127
127
128
writeGenericPointerContainer ( mgpc: mgpc)
128
- sink ( arg: mgpc. ptr. pointee) // $ tainted=119
129
+ sink ( arg: mgpc. ptr. pointee) // $ tainted=writeGenericPointerContainer
130
+ }
131
+
132
+ // ---
133
+
134
+ func testManualMemoryManagement( ) {
135
+ let i1 = sourceInt ( " i1 " )
136
+ let r1 = withUnsafePointer ( to: i1, {
137
+ ptr in
138
+ sink ( arg: ptr) // $ tainted=i1
139
+ sink ( arg: ptr [ 0 ] ) // $ tainted=i1
140
+ sink ( arg: ptr. pointee) // $ MISSING: tainted=i1
141
+ return sourceInt ( " r1 " )
142
+ } )
143
+ sink ( arg: r1) // $ tainted=r1
144
+
145
+ var i2 = sourceInt ( " i2 " )
146
+ let r2 = withUnsafeMutablePointer ( to: & i2, {
147
+ ptr in
148
+ sink ( arg: ptr) // $ tainted=i2
149
+ sink ( arg: ptr [ 0 ] ) // $ tainted=i2
150
+ sink ( arg: ptr. pointee) // $ MISSING: tainted=i2
151
+ ptr. pointee = sourceInt ( " i2_overwrite " )
152
+ sink ( arg: ptr) // $ SPURIOUS: tainted=i2
153
+ sink ( arg: ptr [ 0 ] ) // $ MISSING: tainted=i2_overwrite SPURIOUS: tainted=i2
154
+ sink ( arg: ptr. pointee) // $ tainted=i2_overwrite
155
+ return sourceInt ( " r2 " )
156
+ } )
157
+ sink ( arg: r2) // $ tainted=r2
158
+ sink ( arg: i2) // $ MISSING: tainted=i2_overwrite SPURIOUS: tainted=i2
159
+
160
+ let i3 = sourceInt ( " i3 " )
161
+ let r3 = withUnsafeBytes ( of: i3, {
162
+ ptr in
163
+ sink ( arg: ptr) // $ tainted=i3
164
+ sink ( arg: ptr [ 0 ] ) // $ tainted=i3
165
+ ptr. withMemoryRebound ( to: Int . self, {
166
+ buffer in
167
+ sink ( arg: buffer) // $ tainted=i3
168
+ sink ( arg: buffer [ 0 ] ) // $ tainted=i3
169
+ } )
170
+ let buffer2 = ptr. bindMemory ( to: Int . self)
171
+ sink ( arg: buffer2) // $ tainted=i3
172
+ sink ( arg: buffer2 [ 0 ] ) // $ tainted=i3
173
+ return sourceInt ( " r3 " )
174
+ } )
175
+ sink ( arg: r3) // $ tainted=r3
176
+
177
+ var i4 = sourceInt ( " i4 " )
178
+ let r4 = withUnsafeMutableBytes ( of: & i4, {
179
+ ptr in
180
+ sink ( arg: ptr) // $ tainted=i4
181
+ sink ( arg: ptr [ 0 ] ) // $ tainted=i4
182
+ ptr [ 0 ] = sourceUInt8 ( " i4_partialwrite " )
183
+ sink ( arg: ptr) // $ tainted=i4_partialwrite tainted=i4
184
+ sink ( arg: ptr [ 0 ] ) // $ tainted=i4_partialwrite SPURIOUS: tainted=i4
185
+ return sourceInt ( " r4 " )
186
+ } )
187
+ sink ( arg: r4) // $ tainted=r4
188
+ sink ( arg: i4) // $ tainted=i4 tainted=i4_partialwrite
189
+
190
+ let r5 = withUnsafeTemporaryAllocation ( of: Int . self, capacity: 10 , {
191
+ buffer in
192
+ sink ( arg: buffer)
193
+ sink ( arg: buffer [ 0 ] )
194
+ buffer [ 0 ] = sourceInt ( " buffer5 " )
195
+ sink ( arg: buffer) // $ tainted=buffer5
196
+ sink ( arg: buffer [ 0 ] ) // $ tainted=buffer5
197
+ return sourceInt ( " r5 " )
198
+ } )
199
+ sink ( arg: r5) // $ tainted=r5
200
+
201
+ let r6 = withExtendedLifetime ( sourceInt ( " i6 " ) , {
202
+ return sourceInt ( " r6 " )
203
+ } )
204
+ sink ( arg: r6) // $ tainted=r6
129
205
}
0 commit comments