Hello,
I am researching how arm64e pointer authentication signing is implemented in Swift metadata, and I’ve noticed that for Swift methods, the metadata pointers are signed with a blend constant (the last argument of the .ptrauth IR structure) which is different for each method (I suppose it is derived from the method index, to prevent malicious method substitution, perhaps some hash of a method index number in a class?). In the example below its value is 41900:
@"$s12TestSwiftApp04OpenB5ClassC6getBtrSSyF.ptrauth" = private constant { ptr, i32, i64, i64 } { ptr @"$s12TestSwiftApp04OpenB5ClassC6getBtrSSyF", i32 0, i64 ptrtoint (ptr getelementptr inbounds (<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, i32, i32, i32, i16, i16, i32, i32, ptr, ptr, i64, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr @"$s12TestSwiftApp04OpenB5ClassCMf", i32 0, i32 23) to i64), i64 41900 }, section "llvm.ptrauth", align 8
However another method of the same class has a different blend constant value of 58007:
@"$s12TestSwiftApp04OpenB5ClassC6getStrSSyF.ptrauth" = private constant { ptr, i32, i64, i64 } { ptr @"$s12TestSwiftApp04OpenB5ClassC6getStrSSyF", i32 0, i64 ptrtoint (ptr getelementptr inbounds (<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, i32, i32, i32, i16, i16, i32, i32, ptr, ptr, i64, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr @"$s12TestSwiftApp04OpenB5ClassCMf", i32 0, i32 22) to i64), i64 58007 }, section "llvm.ptrauth", align 8
Can you please explain how this value is derived? I wasn’t able to find this in Swift source code.
Also I was wondering, how stable is implementation of signing of metadata structures in Swift in general, does it stay the same between Swift releases, or does it improve/harden with every new major Swift version?
Thank you