Skip to content

Commit ec615b9

Browse files
authored
Fix ptrauth in RelativeDirectPointer to sign *then* cast (#41355)
1 parent e3b9c98 commit ec615b9

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

include/swift/Basic/RelativePointer.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,16 @@ class RelativeDirectPointerImpl {
442442
return reinterpret_cast<PointerTy>(absolute);
443443
}
444444

445+
void *getWithoutCast() const & {
446+
// Check for null.
447+
if (Nullable && RelativeOffset == 0)
448+
return nullptr;
449+
450+
// The value is addressed relative to `this`.
451+
uintptr_t absolute = detail::applyRelativeOffset(this, RelativeOffset);
452+
return reinterpret_cast<void *>(absolute);
453+
}
454+
445455
/// Apply the offset to a parameter, instead of `this`.
446456
PointerTy getRelative(void *base) const & {
447457
// Check for null.
@@ -511,26 +521,27 @@ class RelativeDirectPointer<T, Nullable, Offset,
511521
}
512522

513523
typename super::PointerTy get() const & {
514-
auto ptr = this->super::get();
524+
void *ptr = this->super::getWithoutCast();
515525
#if SWIFT_PTRAUTH
516526
if (Nullable && !ptr)
517-
return ptr;
518-
return ptrauth_sign_unauthenticated(ptr, ptrauth_key_function_pointer, 0);
527+
return nullptr;
528+
return reinterpret_cast<T *>(
529+
ptrauth_sign_unauthenticated(ptr, ptrauth_key_function_pointer, 0));
519530
#else
520-
return ptr;
531+
return reinterpret_cast<T *>(ptr);
521532
#endif
522533
}
523534

524535
operator typename super::PointerTy() const & {
525536
return this->get();
526537
}
527538

528-
template <typename...ArgTy>
529-
typename std::result_of<T* (ArgTy...)>::type operator()(ArgTy...arg) const {
539+
template <typename... ArgTy>
540+
typename std::result_of<T *(ArgTy...)>::type operator()(ArgTy... arg) const {
530541
#if SWIFT_PTRAUTH
531-
return ptrauth_sign_unauthenticated(this->super::get(),
532-
ptrauth_key_function_pointer,
533-
0)(std::forward<ArgTy>(arg)...);
542+
void *ptr = this->super::getWithoutCast();
543+
return reinterpret_cast<T *>(ptrauth_sign_unauthenticated(
544+
ptr, ptrauth_key_function_pointer, 0))(std::forward<ArgTy>(arg)...);
534545
#else
535546
return this->super::get()(std::forward<ArgTy>(arg)...);
536547
#endif

0 commit comments

Comments
 (0)