Skip to content

Commit aedd073

Browse files
authored
Merge pull request github#12416 from geoffw0/contig
Swift: Model Sequence.withContiguousStorageIfAvailable
2 parents 0a7eecf + 39b6d92 commit aedd073

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
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+
5+
* Added flow models for `Sequence.withContiguousStorageIfAvailable`.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ private class SequenceSummaries extends SummaryModelCsv {
2525
";Sequence;true;joined();;;Argument[-1];ReturnValue;taint",
2626
";Sequence;true;joined(separator:);;;Argument[-1..0];ReturnValue;taint",
2727
";Sequence;true;first(where:);;;Argument[-1];ReturnValue;taint",
28+
";Sequence;true;withContiguousStorageIfAvailable(_:);;;Argument[-1];Argument[0].Parameter[0];taint",
29+
";Sequence;true;withContiguousStorageIfAvailable(_:);;;Argument[0].ReturnValue;ReturnValue;taint",
2830
]
2931
}
3032
}

swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ private class DefaultUnsafeJsEvalAdditionalFlowStep extends UnsafeJsEvalAddition
118118
)
119119
or
120120
exists(CallExpr ce, Expr self, ClosureExpr closure |
121-
ce.getStaticTarget()
122-
.getName()
123-
.matches(["withContiguousStorageIfAvailable(%)", "withUnsafeBufferPointer(%)"]) and
121+
ce.getStaticTarget().getName().matches("withUnsafeBufferPointer(%)") and
124122
self = ce.getQualifier() and
125123
ce.getArgument(0).getExpr() = closure
126124
|

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

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func taintThroughEncodings() {
438438
})
439439
tainted.withContiguousStorageIfAvailable({
440440
ptr in
441-
sink(arg: ptr)
441+
sink(arg: ptr) // $ tainted=366
442442
sink(arg: ptr.baseAddress!) // $ MISSING: tainted=366
443443
})
444444
}
@@ -599,3 +599,52 @@ func untaintedFields() {
599599
sink(arg: String.defaultCStringEncoding)
600600
sink(arg: tainted.isContiguousUTF8)
601601
}
602+
603+
func callbackWithCleanPointer(ptr: UnsafeBufferPointer<String.Element>) throws -> Int {
604+
sink(arg: ptr)
605+
606+
return 0
607+
}
608+
609+
func callbackWithTaintedPointer(ptr: UnsafeBufferPointer<String.Element>) throws -> Int {
610+
sink(arg: ptr) // $ tainted=617
611+
612+
return source()
613+
}
614+
615+
func furtherTaintThroughCallbacks() {
616+
let clean = ""
617+
let tainted = source2()
618+
619+
// return values from the closure (1)
620+
let result1 = clean.withContiguousStorageIfAvailable({
621+
ptr in
622+
return 0
623+
})
624+
sink(arg: result1!)
625+
let result2 = clean.withContiguousStorageIfAvailable({
626+
ptr in
627+
return source()
628+
})
629+
sink(arg: result2!) // $ tainted=627
630+
631+
// return values from the closure (2)
632+
if let result3 = clean.withContiguousStorageIfAvailable({
633+
ptr in
634+
return 0
635+
}) {
636+
sink(arg: result3)
637+
}
638+
if let result4 = clean.withContiguousStorageIfAvailable({
639+
ptr in
640+
return source()
641+
}) {
642+
sink(arg: result4) // $ MISSING: tainted=640
643+
}
644+
645+
// using a non-closure function
646+
let result5 = try? clean.withContiguousStorageIfAvailable(callbackWithCleanPointer)
647+
sink(arg: result5!)
648+
let result6 = try? tainted.withContiguousStorageIfAvailable(callbackWithTaintedPointer)
649+
sink(arg: result6!) // $ tainted=612
650+
}

0 commit comments

Comments
 (0)