Skip to content

Commit 90a62b2

Browse files
committed
Merge branch 'main' into fewer-dataflow-branches
2 parents 7b83947 + 6a48e6e commit 90a62b2

File tree

5 files changed

+159
-23
lines changed

5 files changed

+159
-23
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added flow models for non-member `withUnsafePointer` and similar functions.
5+
* Added flow models for `withMemoryRebound`, `assumingMemoryBound` and `bindMemory` member functions of library pointer classes.

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private class ArraySummaries extends SummaryModelCsv {
3434
";Array;true;withUnsafeBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
3535
";Array;true;withUnsafeMutableBytes(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint",
3636
";Array;true;withUnsafeMutableBytes(_:);;;Argument[-1].CollectionElement;Argument[0].Parameter[0].CollectionElement;taint",
37-
";Array;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0].CollectionElement;Argument[-1].CollectionElement;value",
37+
";Array;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
3838
";Array;true;withUnsafeMutableBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
3939
";ContiguousArray;true;withUnsafeBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint",
4040
";ContiguousArray;true;withUnsafeBufferPointer(_:);;;Argument[-1].CollectionElement;Argument[0].Parameter[0].CollectionElement;value",

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Data.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private class DataSummaries extends SummaryModelCsv {
4747
";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint",
4848
";Data;true;withUnsafeMutableBytes(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint",
4949
";Data;true;withUnsafeMutableBytes(_:);;;Argument[-1].CollectionElement;Argument[0].Parameter[0].CollectionElement;taint",
50-
";Data;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0].CollectionElement;Argument[-1].CollectionElement;value",
50+
";Data;true;withUnsafeMutableBytes(_:);;;Argument[0].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
5151
";Data;true;withUnsafeMutableBytes(_:);;;Argument[0].ReturnValue;ReturnValue;value",
5252
]
5353
}

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/PointerTypes.qll

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,63 @@ private class PointerSummaries extends SummaryModelCsv {
6666
override predicate row(string row) {
6767
row =
6868
[
69+
";UnsafePointer;true;withMemoryRebound(to:capacity:_:);;;Argument[-1].CollectionElement;Argument[2].Parameter[0].CollectionElement;taint",
70+
";UnsafePointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].ReturnValue;ReturnValue;value",
71+
// ---
6972
";UnsafeMutablePointer;true;init(mutating:);;;Argument[0];ReturnValue;taint",
73+
";UnsafeMutablePointer;true;withMemoryRebound(to:capacity:_:);;;Argument[-1].CollectionElement;Argument[2].Parameter[0].CollectionElement;taint",
74+
";UnsafeMutablePointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
75+
";UnsafeMutablePointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].ReturnValue;ReturnValue;value",
76+
// ---
77+
";UnsafeBufferPointer;true;withMemoryRebound(to:_:);;;Argument[-1].CollectionElement;Argument[1].Parameter[0].CollectionElement;taint",
78+
";UnsafeBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
79+
// ---
7080
";UnsafeMutableBufferPointer;true;update(repeating:);;;Argument[0];Argument[-1].CollectionElement;value",
81+
";UnsafeMutableBufferPointer;true;withMemoryRebound(to:_:);;;Argument[-1].CollectionElement;Argument[1].Parameter[0].CollectionElement;taint",
82+
";UnsafeMutableBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
83+
";UnsafeMutableBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
84+
// ---
85+
";UnsafeRawPointer;true;withMemoryRebound(to:capacity:_:);;;Argument[-1].CollectionElement;Argument[2].Parameter[0].CollectionElement;taint",
86+
";UnsafeRawPointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].ReturnValue;ReturnValue;value",
87+
";UnsafeRawPointer;true;assumingMemoryBound(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
88+
";UnsafeRawPointer;true;bindMemory(to:capacity:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
89+
// ---
90+
";UnsafeMutableRawPointer;true;withMemoryRebound(to:capacity:_:);;;Argument[-1].CollectionElement;Argument[2].Parameter[0].CollectionElement;taint",
91+
";UnsafeMutableRawPointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
92+
";UnsafeMutableRawPointer;true;withMemoryRebound(to:capacity:_:);;;Argument[2].ReturnValue;ReturnValue;value",
93+
";UnsafeMutableRawPointer;true;assumingMemoryBound(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
94+
";UnsafeMutableRawPointer;true;bindMemory(to:capacity:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
95+
// ---
96+
";UnsafeRawBufferPointer;true;withMemoryRebound(to:_:);;;Argument[-1].CollectionElement;Argument[1].Parameter[0].CollectionElement;taint",
97+
";UnsafeRawBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
98+
";UnsafeRawBufferPointer;true;assumingMemoryBound(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
99+
";UnsafeRawBufferPointer;true;bindMemory(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
100+
// ---
101+
";UnsafeMutableRawBufferPointer;true;withMemoryRebound(to:_:);;;Argument[-1].CollectionElement;Argument[1].Parameter[0].CollectionElement;taint",
102+
";UnsafeMutableRawBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
103+
";UnsafeMutableRawBufferPointer;true;withMemoryRebound(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
104+
";UnsafeMutableRawBufferPointer;true;assumingMemoryBound(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
105+
";UnsafeMutableRawBufferPointer;true;bindMemory(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
106+
// ---
107+
";Slice;true;withMemoryRebound(to:_:);;;Argument[-1].CollectionElement;Argument[1].Parameter[0].CollectionElement;taint",
108+
";Slice;true;withMemoryRebound(to:_:);;;Argument[1].Parameter[0].CollectionElement;Argument[-1].CollectionElement;taint",
109+
";Slice;true;withMemoryRebound(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
110+
";Slice;true;assumingMemoryBound(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
111+
";Slice;true;bindMemory(to:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
112+
// ---
113+
";;false;withUnsafePointer(to:_:);;;Argument[0];Argument[1].Parameter[0].CollectionElement;taint",
114+
";;false;withUnsafePointer(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
115+
";;false;withUnsafeMutablePointer(to:_:);;;Argument[0];Argument[1].Parameter[0].CollectionElement;taint",
116+
";;false;withUnsafeMutablePointer(to:_:);;;Argument[1].Parameter[0].CollectionElement;Argument[0];value",
117+
";;false;withUnsafeMutablePointer(to:_:);;;Argument[1].ReturnValue;ReturnValue;value",
118+
";;false;withUnsafeBytes(of:_:);;;Argument[0];Argument[1].Parameter[0].CollectionElement;taint",
119+
";;false;withUnsafeBytes(of:_:);;;Argument[1].ReturnValue;ReturnValue;value",
120+
";;false;withUnsafeMutableBytes(of:_:);;;Argument[0];Argument[1].Parameter[0].CollectionElement;taint",
121+
";;false;withUnsafeMutableBytes(of:_:);;;Argument[1].Parameter[0].CollectionElement;Argument[0];taint",
122+
";;false;withUnsafeMutableBytes(of:_:);;;Argument[1].ReturnValue;ReturnValue;value",
123+
";;false;withUnsafeTemporaryAllocation(of:capacity:_:);;;Argument[2].ReturnValue;ReturnValue;value",
124+
";;false;withUnsafeTemporaryAllocation(byteCount:alignment:_:);;;Argument[2].ReturnValue;ReturnValue;value",
125+
";;false;withExtendedLifetime(_:_:);;;Argument[1].ReturnValue;ReturnValue;value",
71126
]
72127
}
73128
}

swift/ql/test/library-tests/dataflow/taint/libraries/unsafepointer.swift

Lines changed: 97 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11

22
// --- stubs ---
33

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 }
67
func sink(arg: Any) {}
78

89
// --- tests ---
@@ -18,14 +19,14 @@ func taintPointer(ptr: UnsafeMutablePointer<String>) {
1819
sink(arg: ptr.pointee)
1920
sink(arg: ptr)
2021

21-
ptr.pointee = sourceString()
22+
ptr.pointee = sourceString("taintPointer")
2223

23-
sink(arg: ptr.pointee) // $ tainted=21
24+
sink(arg: ptr.pointee) // $ tainted=taintPointer
2425
sink(arg: ptr)
2526
}
2627

2728
func clearPointer2(ptr: UnsafeMutablePointer<String>) {
28-
sink(arg: ptr.pointee) // $ tainted=21
29+
sink(arg: ptr.pointee) // $ tainted=taintPointer
2930
sink(arg: ptr)
3031

3132
ptr.pointee = "abc"
@@ -42,12 +43,12 @@ func testMutatingPointerInCall(ptr: UnsafeMutablePointer<String>) {
4243

4344
taintPointer(ptr: ptr) // mutates `ptr` pointee with a tainted value
4445

45-
sink(arg: ptr.pointee) // $ tainted=21
46+
sink(arg: ptr.pointee) // $ tainted=taintPointer
4647
sink(arg: ptr)
4748

4849
clearPointer2(ptr: ptr)
4950

50-
sink(arg: ptr.pointee) // $ SPURIOUS: tainted=21
51+
sink(arg: ptr.pointee) // $ SPURIOUS: tainted=taintPointer
5152
sink(arg: ptr)
5253
}
5354

@@ -57,10 +58,10 @@ func taintBuffer(buffer: UnsafeMutableBufferPointer<UInt8>) {
5758
sink(arg: buffer[0])
5859
sink(arg: buffer)
5960

60-
buffer[0] = sourceUInt8()
61+
buffer[0] = sourceUInt8("taintBuffer")
6162

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
6465
}
6566

6667
func testMutatingBufferInCall(ptr: UnsafeMutablePointer<UInt8>) {
@@ -71,8 +72,8 @@ func testMutatingBufferInCall(ptr: UnsafeMutablePointer<UInt8>) {
7172

7273
taintBuffer(buffer: buffer) // mutates `buffer` contents with a tainted value
7374

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
7677

7778
}
7879

@@ -84,9 +85,9 @@ func taintMyPointer(ptr: MyPointer) {
8485
sink(arg: ptr.pointee)
8586
sink(arg: ptr)
8687

87-
ptr.pointee = sourceString()
88+
ptr.pointee = sourceString("taintMyPointer")
8889

89-
sink(arg: ptr.pointee) // $ tainted=87
90+
sink(arg: ptr.pointee) // $ tainted=taintMyPointer
9091
sink(arg: ptr)
9192
}
9293

@@ -96,7 +97,7 @@ func testMutatingMyPointerInCall(ptr: MyPointer) {
9697

9798
taintMyPointer(ptr: ptr) // mutates `ptr` pointee with a tainted value
9899

99-
sink(arg: ptr.pointee) // $ MISSING: tainted=87
100+
sink(arg: ptr.pointee) // $ MISSING: tainted=taintMyPointer
100101
sink(arg: ptr)
101102
}
102103

@@ -111,19 +112,94 @@ struct MyGenericPointerContainer<T> {
111112
}
112113

113114
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
116117
}
117118

118119
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
121122
}
122123

123124
func testWritingPointerContainersInCalls(mpc: MyPointerContainer, mgpc: MyGenericPointerContainer<Int>) {
124125
writePointerContainer(mpc: mpc)
125-
sink(arg: mpc.ptr.pointee) // $ tainted=114
126+
sink(arg: mpc.ptr.pointee) // $ tainted=writePointerContainer
126127

127128
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
129205
}

0 commit comments

Comments
 (0)