Skip to content

Commit 8fe991f

Browse files
committed
[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
1 parent 8da3ab1 commit 8fe991f

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,7 @@ def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
10721072
def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments", [VariadicMacroArgumentsOmitted]>;
10731073
def MisleadingIndentation : DiagGroup<"misleading-indentation">;
10741074
def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">;
1075+
def PtrAuthWeakSchema : DiagGroup<"ptrauth-weak-schema">;
10751076

10761077
// This covers both the deprecated case (in C++98)
10771078
// and the extension case (in C++11 onwards).

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,10 @@ def err_ptrauth_address_discrimination_invalid : Error<
10461046
def err_ptrauth_extra_discriminator_invalid : Error<
10471047
"invalid extra discriminator flag '%0'; '__ptrauth' requires a value between "
10481048
"'0' and '%1'">;
1049+
def warn_ptrauth_weak_schema
1050+
: Warning<"internal variable %0 is using a weak signing schema for pointer "
1051+
"authentication">,
1052+
InGroup<PtrAuthWeakSchema>;
10491053

10501054
/// main()
10511055
// static main() is not an error in C, just in C++.

clang/lib/Sema/SemaDecl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8357,6 +8357,15 @@ NamedDecl *Sema::ActOnVariableDeclarator(
83578357
D.isFunctionDefinition());
83588358
}
83598359

8360+
// Warn about the use of a weak pointer authentication schema on a variable
8361+
// with internal linkage.
8362+
if (getLangOpts().PointerAuthCalls && NewVD->isFunctionPointerType() &&
8363+
!isExternallyVisible(NewVD->getLinkageInternal())) {
8364+
PointerAuthQualifier Q = NewVD->getType().getQualifiers().getPointerAuth();
8365+
if (!Q || (!Q.isAddressDiscriminated() && Q.getExtraDiscriminator() == 0))
8366+
Diag(NewVD->getLocation(), diag::warn_ptrauth_weak_schema) << NewVD;
8367+
}
8368+
83608369
if (NewTemplate) {
83618370
if (NewVD->isInvalidDecl())
83628371
NewTemplate->setInvalidDecl();
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls -fptrauth-intrinsics -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -triple arm64e-apple-ios -DNO_PTRAUTH -fsyntax-only -verify %s
3+
4+
#if defined(NO_PTRAUTH)
5+
6+
#define FN_PTR_AUTH(address_diversity, constant_discriminator)
7+
// expected-no-diagnostics
8+
9+
#else // !defined(NO_PTRAUTH)
10+
11+
#if !__has_extension(ptrauth_qualifier)
12+
#error __ptrauth qualifier not enabled
13+
#endif
14+
15+
#include <ptrauth.h>
16+
17+
#define FN_PTR_AUTH(address_diversity, constant_discriminator) \
18+
__ptrauth(ptrauth_key_function_pointer, address_diversity, constant_discriminator)
19+
20+
#endif // defined(NO_PTRAUTH)
21+
22+
// Global variables with external linkage and weak pointer authentication should
23+
// not raise any warning.
24+
extern void(* g1_external_weak)(void);
25+
void(* FN_PTR_AUTH(0, 0) g2_external_weak)(void);
26+
27+
// Global variables with internal linkage and strong pointer authentication
28+
// should not raise any warning.
29+
static void(* FN_PTR_AUTH(1, 65535) g1_internal_strong)(void);
30+
static void(* FN_PTR_AUTH(0, 65535) g2_internal_strong)(void);
31+
static void(* FN_PTR_AUTH(1, 0) g3_internal_strong)(void);
32+
33+
#if !defined(NO_PTRAUTH)
34+
// Global variables with internal linkage and weak pointer authentication should
35+
// raise a warning.
36+
static void(* g1_internal_weak)(void);
37+
// expected-warning@-1 {{internal variable 'g1_internal_weak' is using a weak signing schema for pointer authentication}}
38+
static void(* FN_PTR_AUTH(0, 0) g2_internal_weak)(void);
39+
// expected-warning@-1 {{internal variable 'g2_internal_weak' is using a weak signing schema for pointer authentication}}
40+
41+
// Assert that -Wptrauth-weak-schema silences warnings.
42+
#pragma clang diagnostic push
43+
#pragma clang diagnostic ignored "-Wptrauth-weak-schema"
44+
static void(* g3_internal_weak)(void);
45+
#pragma clang diagnostic pop
46+
#endif
47+
48+
void test_local_variables(void) {
49+
#pragma clang diagnostic push
50+
#pragma clang diagnostic ignored "-Wunused-variable"
51+
52+
#if !defined(NO_PTRAUTH)
53+
// Local variables (internal linkage) with weak pointer authentication
54+
// should raise a warning.
55+
static void(* l1_internal_weak)(void);
56+
// expected-warning@-1 {{internal variable 'l1_internal_weak' is using a weak signing schema for pointer authentication}}
57+
static void(* FN_PTR_AUTH(0, 0) l2_internal_weak)(void);
58+
// expected-warning@-1 {{internal variable 'l2_internal_weak' is using a weak signing schema for pointer authentication}}
59+
#endif
60+
61+
// Local variables (internal linkage) with strong pointer authentication
62+
// should not raise any warning.
63+
void(* FN_PTR_AUTH(1, 65535) l1_internal_strong)(void);
64+
void(* FN_PTR_AUTH(0, 65535) l2_internal_strong)(void);
65+
void(* FN_PTR_AUTH(1, 0) l3_internal_strong)(void);
66+
67+
#pragma clang diagnostic pop
68+
}

0 commit comments

Comments
 (0)