Skip to content

Commit 3193ceb

Browse files
authored
Merge pull request #15052 from geoffw0/pointermodels
Swift: Expand models for UnsafePointer and friends
2 parents 9cb0bb2 + 36d0148 commit 3193ceb

File tree

7 files changed

+240
-7
lines changed

7 files changed

+240
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Expanded flow models for `UnsafePointer` and similar classes.

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

Lines changed: 124 additions & 1 deletion
Large diffs are not rendered by default.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ func taintThroughMutablePointer() {
106106
sink(arg: ptr5) // $ tainted=array5write
107107
sink(arg: ptr5[0]) // $ tainted=array5write
108108
ptr4.copyBytes(from: ptr5)
109-
sink(arg: ptr4)
110-
sink(arg: ptr4[0]) // $ MISSING: tainted=array5write
109+
sink(arg: ptr4) // $ tainted=array5write
110+
sink(arg: ptr4[0]) // $ tainted=array5write
111111
return source("return5")
112112
})
113113
sink(arg: return5) // $ tainted=return5

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,11 +464,11 @@ func taintFromUInt8Array() {
464464
sink(arg: buffer[0])
465465
sink(arg: taintedUInt8Values[0]) // $ tainted=450
466466
let _ = buffer.initialize(from: taintedUInt8Values)
467-
sink(arg: buffer[0]) // $ MISSING: tainted=450
467+
sink(arg: buffer[0]) // $ tainted=450
468468
return 256
469469
}
470470
)
471-
sink(arg: r2) // $ MISSING: tainted=450
471+
sink(arg: r2) // $ tainted=450
472472
let r3 = String(unsafeUninitializedCapacity: 256, initializingUTF8With: {
473473
(buffer: UnsafeMutableBufferPointer<UInt8>) -> Int in
474474
sink(arg: buffer[0])

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,109 @@ func testManualMemoryManagement() {
203203
})
204204
sink(arg: r6) // $ tainted=r6
205205
}
206+
207+
// ---
208+
209+
func testUnsafePointers() {
210+
let ptr1 = UnsafeMutablePointer<Int>.allocate(capacity: 1024)
211+
ptr1.initialize(repeating: 0, count: 1024)
212+
sink(arg: ptr1[0])
213+
ptr1.initialize(repeating: sourceInt("ptr1"), count: 1024)
214+
sink(arg: ptr1[0]) // $ tainted=ptr1
215+
216+
let ptr2 = UnsafeMutablePointer<Int>.allocate(capacity: 1)
217+
ptr2.initialize(to: 0)
218+
sink(arg: ptr2.pointee)
219+
ptr2.initialize(to: sourceInt("ptr2"))
220+
sink(arg: ptr2.pointee) // $ MISSING: tainted=ptr2
221+
sink(arg: ptr2.move()) // $ tainted=ptr2
222+
223+
let ptr3 = UnsafeMutablePointer<Int>.allocate(capacity: 1024)
224+
ptr3.initialize(repeating: 0, count: 1024)
225+
sink(arg: ptr3[0])
226+
ptr3.assign(repeating: sourceInt("ptr3"), count: 1024)
227+
sink(arg: ptr3[0]) // $ tainted=ptr3
228+
229+
let ptr4 = UnsafeMutablePointer<Int>.allocate(capacity: 1024)
230+
ptr4.initialize(repeating: 0, count: 1024)
231+
ptr4.update(from: ptr1, count: 512)
232+
sink(arg: ptr4[0]) // $ tainted=ptr1
233+
}
234+
235+
func testRawPointers() {
236+
let raw1 = UnsafeMutableRawPointer.allocate(byteCount: 1024, alignment: 4)
237+
raw1.initializeMemory(as: Int.self, repeating: 0, count: 1024)
238+
sink(arg: raw1.load(fromByteOffset: 0, as: Int.self))
239+
raw1.initializeMemory(as: Int.self, repeating: sourceInt("raw1"), count: 1024)
240+
sink(arg: raw1.load(fromByteOffset: 0, as: Int.self)) // $ tainted=raw1
241+
242+
let raw2 = UnsafeMutableRawPointer.allocate(byteCount: 1024, alignment: 4)
243+
raw2.initializeMemory(as: Int.self, repeating: 0, count: 1024)
244+
//raw2.storeBytes(of: 0, toByteOffset: 0, as: Int.self) --- this line fails on Linux
245+
sink(arg: raw2.load(fromByteOffset: 0, as: Int.self))
246+
//raw2.storeBytes(of: sourceInt("raw2"), toByteOffset: 0, as: Int.self) --- this line fails on Linux
247+
sink(arg: raw2.load(fromByteOffset: 0, as: Int.self)) // $ MISSING: tainted=raw2
248+
249+
let raw3 = UnsafeRawPointer(raw1)
250+
sink(arg: raw3.load(fromByteOffset: 0, as: Int.self)) // $ tainted=raw1
251+
let raw4 = UnsafeRawBufferPointer(start: raw3, count: MemoryLayout<Int>.size)
252+
sink(arg: raw4[0]) // $ tainted=raw1
253+
}
254+
255+
func testRawPointerConversion() {
256+
let i1 = sourceInt("i1")
257+
withUnsafeBytes(of: i1, {
258+
ptr in // UnsafeRawBufferPointer
259+
sink(arg: ptr[0]) // $ tainted=i1
260+
261+
let ptr2 = UnsafeRawBufferPointer(ptr)
262+
sink(arg: ptr2[0]) // $ tainted=i1
263+
264+
let ptr3 = UnsafeMutableRawBufferPointer(mutating: ptr)
265+
sink(arg: ptr3[0]) // $ tainted=i1
266+
267+
let ptr4 = UnsafeMutableRawBufferPointer.allocate(byteCount: 8, alignment: 0)
268+
ptr4.copyBytes(from: ptr)
269+
sink(arg: ptr4[0]) // $ tainted=i1
270+
271+
let ptr5 = UnsafeMutableRawBufferPointer.allocate(byteCount: 8, alignment: 0)
272+
ptr5.copyMemory(from: ptr)
273+
sink(arg: ptr5[0]) // $ tainted=i1
274+
275+
let i = ptr.load(fromByteOffset: 0, as: Int.self)
276+
sink(arg: i) // $ tainted=i1
277+
})
278+
279+
var i2 = sourceInt("i2")
280+
withUnsafeMutableBytes(of: &i2, {
281+
ptr in // UnsafeMutableRawBufferPointer
282+
sink(arg: ptr[0]) // $ tainted=i2
283+
284+
let ptr2 = UnsafeRawBufferPointer(ptr)
285+
sink(arg: ptr2[0]) // $ tainted=i2
286+
287+
let ptr3 = UnsafeMutableRawBufferPointer(ptr)
288+
sink(arg: ptr3[0]) // $ tainted=i2
289+
})
290+
}
291+
292+
func testSlice() {
293+
let buffer = UnsafeMutableBufferPointer<Int>.allocate(capacity: 1024)
294+
buffer.initialize(repeating: 0)
295+
sink(arg: buffer[0])
296+
buffer[0] = sourceInt("buffer")
297+
sink(arg: buffer[0]) // $ tainted=buffer
298+
299+
let slice = Slice(base: buffer, bounds: 0 ..< 10)
300+
sink(arg: slice[0]) // $ tainted=buffer
301+
sink(arg: slice.base[0]) // $ MISSING: tainted=buffer
302+
303+
let buffer2 = UnsafeMutableBufferPointer(rebasing: slice)
304+
sink(arg: buffer2[0]) // $ tainted=buffer
305+
306+
let buffer3 = UnsafeMutableBufferPointer<Int>.allocate(capacity: 1024)
307+
buffer3.initialize(repeating: 0)
308+
sink(arg: buffer3[0])
309+
buffer3[10 ..< 20] = buffer[0 ..< 10]
310+
sink(arg: buffer3[0]) // $ tainted=buffer
311+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
failures
21
testFailures
2+
failures

swift/ql/test/query-tests/Security/CWE-022/testPathInjection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ func test(buffer1: UnsafeMutablePointer<UInt8>, buffer2: UnsafeMutablePointer<UI
418418
_ = sqlite3_open_v2(remoteString, &db, 0, nil) // $ hasPathInjection=289
419419

420420
sqlite3_temp_directory = UnsafeMutablePointer<CChar>(mutating: NSString(string: "myFile.sqlite3").utf8String) // GOOD
421-
sqlite3_temp_directory = UnsafeMutablePointer<CChar>(mutating: NSString(string: remoteString).utf8String) // $ hasPathInjection=289
421+
sqlite3_temp_directory = UnsafeMutablePointer<CChar>(mutating: NSString(string: remoteString).utf8String) // $ MISSING: hasPathInjection=289
422422

423423
// SQLite.swift
424424

0 commit comments

Comments
 (0)