Skip to content

Commit 2701a08

Browse files
committed
[metadata prespecialization] Ptrauth for compared protocol conformances.
Two protocol conformance descriptors are passed to swift_compareProtocolConformanceDecriptors from generic metadata accessors when there is a canonical prespecialization and one of the generic arguments has a protocol requirement. Previously, the descriptors were incorrectly being passed without ptrauth processing: one from the witness table in the arguments that are passed in to the accessor and one known statically. Here, the descriptor in the witness table is authed using the ProtocolConformanceDescriptor schema. Then, both descriptors are signed using the ProtocolConformanceDescriptorsAsArguments schema. Finally, in the runtime function, the descriptors are authed.
1 parent a5f0069 commit 2701a08

File tree

7 files changed

+51
-1
lines changed

7 files changed

+51
-1
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,9 @@ namespace SpecialPointerAuthDiscriminators {
11181118
/// Runtime function variables exported by the runtime.
11191119
const uint16_t RuntimeFunctionEntry = 0x625b;
11201120

1121+
/// Protocol conformance descriptors.
1122+
const uint16_t ProtocolConformanceDescriptor = 0xc6eb;
1123+
11211124
/// Value witness functions.
11221125
const uint16_t InitializeBufferWithCopyOfBuffer = 0xda4a;
11231126
const uint16_t Destroy = 0x04f8;

include/swift/AST/IRGenOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
117117
/// Type descriptor data pointers when passed as arguments.
118118
PointerAuthSchema TypeDescriptorsAsArguments;
119119

120+
/// Protocol conformance descriptors.
121+
PointerAuthSchema ProtocolConformanceDescriptors;
122+
123+
/// Protocol conformance descriptors when passed as arguments.
124+
PointerAuthSchema ProtocolConformanceDescriptorsAsArguments;
125+
120126
/// Resumption functions from yield-once coroutines.
121127
PointerAuthSchema YieldOnceResumeFunctions;
122128

lib/IRGen/GenPointerAuth.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ PointerAuthEntity::getDeclDiscriminator(IRGenModule &IGM) const {
309309
case Special::TypeDescriptor:
310310
case Special::TypeDescriptorAsArgument:
311311
return SpecialPointerAuthDiscriminators::TypeDescriptor;
312+
case Special::ProtocolConformanceDescriptor:
313+
case Special::ProtocolConformanceDescriptorAsArgument:
314+
return SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor;
312315
case Special::PartialApplyCapture:
313316
return PointerAuthDiscriminator_PartialApplyCapture;
314317
case Special::KeyPathDestroy:

lib/IRGen/GenPointerAuth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class PointerAuthEntity {
6262
KeyPathInitializer,
6363
KeyPathMetadataAccessor,
6464
DynamicReplacementKey,
65+
ProtocolConformanceDescriptor,
66+
ProtocolConformanceDescriptorAsArgument,
6567
};
6668

6769
private:

lib/IRGen/IRGen.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,11 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
651651
opts.SwiftDynamicReplacementKeys =
652652
PointerAuthSchema(dataKey, /*address*/ true, Discrimination::Decl);
653653

654+
opts.ProtocolConformanceDescriptors =
655+
PointerAuthSchema(dataKey, /*address*/ true, Discrimination::Decl);
656+
opts.ProtocolConformanceDescriptorsAsArguments =
657+
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
658+
654659
// Coroutine resumption functions are never stored globally in the ABI,
655660
// so we can do some things that aren't normally okay to do. However,
656661
// we can't use ASIB because that would break ARM64 interoperation.

lib/IRGen/MetadataRequest.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,7 @@ static void emitCanonicalSpecializationsForGenericTypeMetadataAccessFunction(
19701970
} else {
19711971
RootProtocolConformance *rootConformance =
19721972
concreteConformance->getRootConformance();
1973-
auto *expectedDescriptor =
1973+
llvm::Value *expectedDescriptor =
19741974
IGF.IGM.getAddrOfProtocolConformanceDescriptor(rootConformance);
19751975
auto *witnessTable = valueAtIndex(requirementIndex);
19761976
auto *witnessBuffer =
@@ -1981,6 +1981,32 @@ static void emitCanonicalSpecializationsForGenericTypeMetadataAccessFunction(
19811981
uncastProvidedDescriptor,
19821982
IGM.ProtocolConformanceDescriptorPtrTy);
19831983

1984+
// Auth the stored descriptor.
1985+
auto storedScheme =
1986+
IGF.IGM.getOptions().PointerAuth.ProtocolConformanceDescriptors;
1987+
if (storedScheme) {
1988+
auto authInfo = PointerAuthInfo::emit(
1989+
IGF, storedScheme, witnessTable,
1990+
PointerAuthEntity::Special::ProtocolConformanceDescriptor);
1991+
providedDescriptor =
1992+
emitPointerAuthAuth(IGF, providedDescriptor, authInfo);
1993+
}
1994+
1995+
// Sign the descriptors.
1996+
auto argScheme =
1997+
IGF.IGM.getOptions()
1998+
.PointerAuth.ProtocolConformanceDescriptorsAsArguments;
1999+
if (argScheme) {
2000+
auto authInfo = PointerAuthInfo::emit(
2001+
IGF, argScheme, nullptr,
2002+
PointerAuthEntity::Special::
2003+
ProtocolConformanceDescriptorAsArgument);
2004+
expectedDescriptor =
2005+
emitPointerAuthSign(IGF, expectedDescriptor, authInfo);
2006+
providedDescriptor =
2007+
emitPointerAuthSign(IGF, providedDescriptor, authInfo);
2008+
}
2009+
19842010
auto *call = IGF.Builder.CreateCall(
19852011
IGF.IGM.getCompareProtocolConformanceDescriptorsFn(),
19862012
{providedDescriptor, expectedDescriptor});

stdlib/public/runtime/Metadata.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4996,6 +4996,11 @@ const WitnessTable *swift::swift_getAssociatedConformanceWitness(
49964996
bool swift::swift_compareProtocolConformanceDescriptors(
49974997
const ProtocolConformanceDescriptor *lhs,
49984998
const ProtocolConformanceDescriptor *rhs) {
4999+
lhs = swift_auth_data_non_address(
5000+
lhs, SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor);
5001+
rhs = swift_auth_data_non_address(
5002+
rhs, SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor);
5003+
49995004
return MetadataCacheKey::compareProtocolConformanceDescriptors(lhs, rhs) == 0;
50005005
}
50015006

0 commit comments

Comments
 (0)