mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
StackProtection: ignore pointers with no stores
Stack protection only protects against overflows, but not against out of bounds reads. rdar://105231457
This commit is contained in:
@@ -486,6 +486,11 @@ private extension Instruction {
|
||||
if !atp.needsStackProtection {
|
||||
return nil
|
||||
}
|
||||
var hasNoStores = NoStores()
|
||||
if hasNoStores.walkDownUses(ofValue: atp, path: SmallProjectionPath()) == .continueWalk {
|
||||
return nil
|
||||
}
|
||||
|
||||
// The result of an `address_to_pointer` may be used in any unsafe way, e.g.
|
||||
// passed to a C function.
|
||||
baseAddr = atp.operand
|
||||
@@ -493,6 +498,11 @@ private extension Instruction {
|
||||
if !ia.needsStackProtection {
|
||||
return nil
|
||||
}
|
||||
var hasNoStores = NoStores()
|
||||
if hasNoStores.walkDownUses(ofAddress: ia, path: SmallProjectionPath()) == .continueWalk {
|
||||
return nil
|
||||
}
|
||||
|
||||
// `index_addr` is unsafe if not used for tail-allocated elements (e.g. in Array).
|
||||
baseAddr = ia.base
|
||||
default:
|
||||
@@ -509,6 +519,29 @@ private extension Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if there are no stores to an address or raw pointer.
|
||||
private struct NoStores : ValueDefUseWalker, AddressDefUseWalker {
|
||||
var walkDownCache = WalkerCache<SmallProjectionPath>()
|
||||
|
||||
mutating func leafUse(value: Operand, path: SmallProjectionPath) -> WalkResult {
|
||||
if let ptai = value.instruction as? PointerToAddressInst {
|
||||
return walkDownUses(ofAddress: ptai, path: path)
|
||||
}
|
||||
return .abortWalk
|
||||
}
|
||||
|
||||
mutating func leafUse(address: Operand, path: SmallProjectionPath) -> WalkResult {
|
||||
switch address.instruction {
|
||||
case is LoadInst:
|
||||
return .continueWalk
|
||||
case let cai as CopyAddrInst:
|
||||
return address == cai.sourceOperand ? .continueWalk : .abortWalk
|
||||
default:
|
||||
return .abortWalk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension Function {
|
||||
func setNeedsStackProtection(_ context: FunctionPassContext) {
|
||||
if !needsStackProtection {
|
||||
|
||||
Reference in New Issue
Block a user