Merge pull request #66746 from eeckstein/stack-protection

StackProtection: treat source-operands of `memcpy` and `memmove` intrinsics as read-only
This commit is contained in:
eeckstein
2023-06-19 22:32:52 +02:00
committed by GitHub
5 changed files with 51 additions and 2 deletions

View File

@@ -524,10 +524,19 @@ private struct NoStores : ValueDefUseWalker, AddressDefUseWalker {
var walkDownCache = WalkerCache<SmallProjectionPath>()
mutating func leafUse(value: Operand, path: SmallProjectionPath) -> WalkResult {
if let ptai = value.instruction as? PointerToAddressInst {
switch value.instruction {
case let ptai as PointerToAddressInst:
return walkDownUses(ofAddress: ptai, path: path)
case let bi as BuiltinInst:
switch bi.intrinsicID {
case .memcpy, .memmove:
return value.index != 0 ? .continueWalk : .abortWalk
default:
return .abortWalk
}
default:
return .abortWalk
}
return .abortWalk
}
mutating func leafUse(address: Operand, path: SmallProjectionPath) -> WalkResult {

View File

@@ -399,6 +399,10 @@ final public class BuiltinInst : SingleValueInstruction {
return bridged.BuiltinInst_getID()
}
public var intrinsicID: BridgedInstruction.IntrinsicID {
return bridged.BuiltinInst_getIntrinsicID()
}
public var substitutionMap: SubstitutionMap {
SubstitutionMap(bridged.BuiltinInst_getSubstitutionMap())
}

View File

@@ -525,6 +525,19 @@ struct BridgedInstruction {
return getAs<swift::BuiltinInst>()->getBuiltinInfo().ID;
}
enum class IntrinsicID {
memcpy, memmove,
unknown
};
IntrinsicID BuiltinInst_getIntrinsicID() const {
switch (getAs<swift::BuiltinInst>()->getIntrinsicInfo().ID) {
case llvm::Intrinsic::memcpy: return IntrinsicID::memcpy;
case llvm::Intrinsic::memmove: return IntrinsicID::memmove;
default: return IntrinsicID::unknown;
}
}
SWIFT_IMPORT_UNSAFE
swift::SubstitutionMap BuiltinInst_getSubstitutionMap() const {
return getAs<swift::BuiltinInst>()->getSubstitutions();

View File

@@ -676,4 +676,20 @@ bb0:
return %12 : $()
}
// CHECK-LABEL: sil @test_mem_intrinsics
// CHECK-NOT: copy_addr
// CHECK: } // end sil function 'test_mem_intrinsics'
sil @test_mem_intrinsics : $@convention(thin) (Builtin.RawPointer, Int64) -> () {
bb0(%0 : $Builtin.RawPointer, %1: $Int64):
%2 = alloc_stack $Int64
store %1 to %2 : $*Int64
%4 = address_to_pointer [stack_protection] %2 : $*Int64 to $Builtin.RawPointer
%5 = integer_literal $Builtin.Int64, 8
%6 = integer_literal $Builtin.Int1, 0
%7 = builtin "int_memcpy_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %4 : $Builtin.RawPointer, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $()
%8 = builtin "int_memmove_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %4 : $Builtin.RawPointer, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $()
dealloc_stack %2 : $*Int64
%10 = tuple ()
return %10 : $()
}

View File

@@ -118,3 +118,10 @@ public func loadUnaligned(_ urp: UnsafeRawPointer) -> Int {
return urp.loadUnaligned(as: Int.self)
}
// CHECK-LABEL: sil @$s4test19storeBytesToPointeryySv_SitF :
// CHECK-NOT: copy_addr
// CHECK: } // end sil function '$s4test19storeBytesToPointeryySv_SitF'
public func storeBytesToPointer(_ p: UnsafeMutableRawPointer, _ i: Int) {
p.storeBytes(of: i, as: Int.self)
}