@@ -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