[clang] [clang][ptrauth] Warn about the use of a weak signing schema (PR #157779)

Martin Balao Alonso via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 9 18:57:11 PDT 2025


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 <martin.uy at apple.com>
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 at -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 at -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 at -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 at -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
+}



More information about the cfe-commits mailing list