https://github.com/martinuy created https://github.com/llvm/llvm-project/pull/157779
In this change we added the -Wptrauth-weak-schema diagnostic (enabled by default on targets that support pointer authentication) to warn about the use of a weak signing schema for function pointers stored in global variables with internal linkage. rdar://159299739 >From 91b44455ef04db0eaed778d34514acc3622eee54 Mon Sep 17 00:00:00 2001 From: Martin Balao Alonso <[email protected]> Date: Tue, 9 Sep 2025 18:29:38 -0700 Subject: [PATCH] [clang][ptrauth] Warn about the use of a weak signing schema In this change we added the -Wptrauth-weak-schema diagnostic (enabled by default on targets that support pointer authentication) to warn about the use of a weak signing schema for function pointers stored in global variables with internal linkage. rdar://159299739 --- clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td | 4 ++ clang/lib/Sema/SemaDecl.cpp | 9 +++ clang/test/Sema/ptrauth-weak-schema.c | 68 +++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 clang/test/Sema/ptrauth-weak-schema.c diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 0c994e0b5ca4d..de10c39a4ac3c 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1072,6 +1072,7 @@ def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments", [VariadicMacroArgumentsOmitted]>; def MisleadingIndentation : DiagGroup<"misleading-indentation">; def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">; +def PtrAuthWeakSchema : DiagGroup<"ptrauth-weak-schema">; // This covers both the deprecated case (in C++98) // and the extension case (in C++11 onwards). diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ecdbeb0687cac..b266fe0536f60 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1046,6 +1046,10 @@ def err_ptrauth_address_discrimination_invalid : Error< def err_ptrauth_extra_discriminator_invalid : Error< "invalid extra discriminator flag '%0'; '__ptrauth' requires a value between " "'0' and '%1'">; +def warn_ptrauth_weak_schema + : Warning<"internal variable %0 is using a weak signing schema for pointer " + "authentication">, + InGroup<PtrAuthWeakSchema>; /// main() // static main() is not an error in C, just in C++. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7c1459e320167..a8eb1188916b7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8357,6 +8357,15 @@ NamedDecl *Sema::ActOnVariableDeclarator( D.isFunctionDefinition()); } + // Warn about the use of a weak pointer authentication schema on a variable + // with internal linkage. + if (getLangOpts().PointerAuthCalls && NewVD->isFunctionPointerType() && + !isExternallyVisible(NewVD->getLinkageInternal())) { + PointerAuthQualifier Q = NewVD->getType().getQualifiers().getPointerAuth(); + if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0)) + Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema) << NewVD; + } + if (NewTemplate) { if (NewVD->isInvalidDecl()) NewTemplate->setInvalidDecl(); diff --git a/clang/test/Sema/ptrauth-weak-schema.c b/clang/test/Sema/ptrauth-weak-schema.c new file mode 100644 index 0000000000000..792ff9f99627c --- /dev/null +++ b/clang/test/Sema/ptrauth-weak-schema.c @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls -fptrauth-intrinsics -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple arm64e-apple-ios -DNO_PTRAUTH -fsyntax-only -verify %s + +#if defined(NO_PTRAUTH) + +#define FN_PTR_AUTH(address_diversity, constant_discriminator) +// expected-no-diagnostics + +#else // !defined(NO_PTRAUTH) + +#if !__has_extension(ptrauth_qualifier) +#error __ptrauth qualifier not enabled +#endif + +#include <ptrauth.h> + +#define FN_PTR_AUTH(address_diversity, constant_discriminator) \ + __ptrauth(ptrauth_key_function_pointer, address_diversity, constant_discriminator) + +#endif // defined(NO_PTRAUTH) + +// Global variables with external linkage and weak pointer authentication should +// not raise any warning. +extern void(* g1_external_weak)(void); +void(* FN_PTR_AUTH(0, 0) g2_external_weak)(void); + +// Global variables with internal linkage and strong pointer authentication +// should not raise any warning. +static void(* FN_PTR_AUTH(1, 65535) g1_internal_strong)(void); +static void(* FN_PTR_AUTH(0, 65535) g2_internal_strong)(void); +static void(* FN_PTR_AUTH(1, 0) g3_internal_strong)(void); + +#if !defined(NO_PTRAUTH) +// Global variables with internal linkage and weak pointer authentication should +// raise a warning. +static void(* g1_internal_weak)(void); +// expected-warning@-1 {{internal variable 'g1_internal_weak' is using a weak signing schema for pointer authentication}} +static void(* FN_PTR_AUTH(0, 0) g2_internal_weak)(void); +// expected-warning@-1 {{internal variable 'g2_internal_weak' is using a weak signing schema for pointer authentication}} + +// Assert that -Wptrauth-weak-schema silences warnings. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wptrauth-weak-schema" +static void(* g3_internal_weak)(void); +#pragma clang diagnostic pop +#endif + +void test_local_variables(void) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunused-variable" + + #if !defined(NO_PTRAUTH) + // Local variables (internal linkage) with weak pointer authentication + // should raise a warning. + static void(* l1_internal_weak)(void); + // expected-warning@-1 {{internal variable 'l1_internal_weak' is using a weak signing schema for pointer authentication}} + static void(* FN_PTR_AUTH(0, 0) l2_internal_weak)(void); + // expected-warning@-1 {{internal variable 'l2_internal_weak' is using a weak signing schema for pointer authentication}} + #endif + + // Local variables (internal linkage) with strong pointer authentication + // should not raise any warning. + void(* FN_PTR_AUTH(1, 65535) l1_internal_strong)(void); + void(* FN_PTR_AUTH(0, 65535) l2_internal_strong)(void); + void(* FN_PTR_AUTH(1, 0) l3_internal_strong)(void); + + #pragma clang diagnostic pop +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
