Skip to content

Commit a70b040

Browse files
authored
Merge pull request #66746 from eeckstein/stack-protection
StackProtection: treat source-operands of `memcpy` and `memmove` intrinsics as read-only
2 parents 189dfc8 + 86f2ced commit a70b040

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

SwiftCompilerSources/Sources/Optimizer/ModulePasses/StackProtection.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,19 @@ private struct NoStores : ValueDefUseWalker, AddressDefUseWalker {
524524
var walkDownCache = WalkerCache<SmallProjectionPath>()
525525

526526
mutating func leafUse(value: Operand, path: SmallProjectionPath) -> WalkResult {
527-
if let ptai = value.instruction as? PointerToAddressInst {
527+
switch value.instruction {
528+
case let ptai as PointerToAddressInst:
528529
return walkDownUses(ofAddress: ptai, path: path)
530+
case let bi as BuiltinInst:
531+
switch bi.intrinsicID {
532+
case .memcpy, .memmove:
533+
return value.index != 0 ? .continueWalk : .abortWalk
534+
default:
535+
return .abortWalk
536+
}
537+
default:
538+
return .abortWalk
529539
}
530-
return .abortWalk
531540
}
532541

533542
mutating func leafUse(address: Operand, path: SmallProjectionPath) -> WalkResult {

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@ final public class BuiltinInst : SingleValueInstruction {
399399
return bridged.BuiltinInst_getID()
400400
}
401401

402+
public var intrinsicID: BridgedInstruction.IntrinsicID {
403+
return bridged.BuiltinInst_getIntrinsicID()
404+
}
405+
402406
public var substitutionMap: SubstitutionMap {
403407
SubstitutionMap(bridged.BuiltinInst_getSubstitutionMap())
404408
}

include/swift/SIL/SILBridging.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,19 @@ struct BridgedInstruction {
525525
return getAs<swift::BuiltinInst>()->getBuiltinInfo().ID;
526526
}
527527

528+
enum class IntrinsicID {
529+
memcpy, memmove,
530+
unknown
531+
};
532+
533+
IntrinsicID BuiltinInst_getIntrinsicID() const {
534+
switch (getAs<swift::BuiltinInst>()->getIntrinsicInfo().ID) {
535+
case llvm::Intrinsic::memcpy: return IntrinsicID::memcpy;
536+
case llvm::Intrinsic::memmove: return IntrinsicID::memmove;
537+
default: return IntrinsicID::unknown;
538+
}
539+
}
540+
528541
SWIFT_IMPORT_UNSAFE
529542
swift::SubstitutionMap BuiltinInst_getSubstitutionMap() const {
530543
return getAs<swift::BuiltinInst>()->getSubstitutions();

test/SILOptimizer/stack_protection.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,4 +676,20 @@ bb0:
676676
return %12 : $()
677677
}
678678

679+
// CHECK-LABEL: sil @test_mem_intrinsics
680+
// CHECK-NOT: copy_addr
681+
// CHECK: } // end sil function 'test_mem_intrinsics'
682+
sil @test_mem_intrinsics : $@convention(thin) (Builtin.RawPointer, Int64) -> () {
683+
bb0(%0 : $Builtin.RawPointer, %1: $Int64):
684+
%2 = alloc_stack $Int64
685+
store %1 to %2 : $*Int64
686+
%4 = address_to_pointer [stack_protection] %2 : $*Int64 to $Builtin.RawPointer
687+
%5 = integer_literal $Builtin.Int64, 8
688+
%6 = integer_literal $Builtin.Int1, 0
689+
%7 = builtin "int_memcpy_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %4 : $Builtin.RawPointer, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $()
690+
%8 = builtin "int_memmove_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %4 : $Builtin.RawPointer, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $()
691+
dealloc_stack %2 : $*Int64
692+
%10 = tuple ()
693+
return %10 : $()
694+
}
679695

test/SILOptimizer/stack_protection.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,10 @@ public func loadUnaligned(_ urp: UnsafeRawPointer) -> Int {
118118
return urp.loadUnaligned(as: Int.self)
119119
}
120120

121+
// CHECK-LABEL: sil @$s4test19storeBytesToPointeryySv_SitF :
122+
// CHECK-NOT: copy_addr
123+
// CHECK: } // end sil function '$s4test19storeBytesToPointeryySv_SitF'
124+
public func storeBytesToPointer(_ p: UnsafeMutableRawPointer, _ i: Int) {
125+
p.storeBytes(of: i, as: Int.self)
126+
}
127+

0 commit comments

Comments
 (0)