Skip to content

Commit f54025d

Browse files
committed
[sanitizer] Fix prctl interceptor causing PAC authentication failure after PAC key reset
1 parent 74275a1 commit f54025d

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,8 +1285,34 @@ INTERCEPTOR(int, puts, char *s) {
12851285
#endif
12861286

12871287
#if SANITIZER_INTERCEPT_PRCTL
1288-
INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
1289-
unsigned long arg4, unsigned long arg5) {
1288+
1289+
# if defined(__aarch64__)
1290+
// https://llvm.org/docs/PointerAuth.html
1291+
// AArch64 is currently the only architecture with full PAC support.
1292+
// Avoid adding PAC instructions to prevent crashes caused by
1293+
// prctl(PR_PAC_RESET_KEYS, ...). Since PR_PAC_RESET_KEYS resets the
1294+
// authentication key, using the old key afterward will lead to a crash.
1295+
1296+
# if defined(__ARM_FEATURE_BTI_DEFAULT)
1297+
# define BRANCH_PROTECTION_ATTRIBUTE \
1298+
__attribute__((target("branch-protection=bti")))
1299+
# else
1300+
# define BRANCH_PROTECTION_ATTRIBUTE \
1301+
__attribute__((target("branch-protection=none")))
1302+
# endif
1303+
1304+
# define PRCTL_INTERCEPTOR(ret_type, func, ...) \
1305+
DEFINE_REAL(ret_type, func, __VA_ARGS__) \
1306+
DECLARE_WRAPPER(ret_type, func, __VA_ARGS__) \
1307+
extern "C" INTERCEPTOR_ATTRIBUTE BRANCH_PROTECTION_ATTRIBUTE ret_type \
1308+
WRAP(func)(__VA_ARGS__)
1309+
1310+
# else
1311+
# define PRCTL_INTERCEPTOR INTERCEPTOR
1312+
# endif
1313+
1314+
PRCTL_INTERCEPTOR(int, prctl, int option, unsigned long arg2,
1315+
unsigned long arg3, unsigned long arg4, unsigned long arg5) {
12901316
void *ctx;
12911317
COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
12921318
static const int PR_SET_NAME = 15;
@@ -1326,7 +1352,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
13261352
}
13271353
return res;
13281354
}
1329-
#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
1355+
# define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
13301356
#else
13311357
#define INIT_PRCTL
13321358
#endif // SANITIZER_INTERCEPT_PRCTL

0 commit comments

Comments
 (0)