[compiler-rt] 6bbf0c3 - [sanitizer] Fix prctl interceptor causing PAC authentication failure (#153081)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 06:41:57 PDT 2025
Author: Fei Peng
Date: 2025-09-03T15:41:53+02:00
New Revision: 6bbf0c30ca4449e325beb2d28db00d258d3a1a10
URL: https://github.com/llvm/llvm-project/commit/6bbf0c30ca4449e325beb2d28db00d258d3a1a10
DIFF: https://github.com/llvm/llvm-project/commit/6bbf0c30ca4449e325beb2d28db00d258d3a1a10.diff
LOG: [sanitizer] Fix prctl interceptor causing PAC authentication failure (#153081)
The root cause of this crash is that prctl(PR_PAC_RESET_KEYS) generates
a new PAC key. As a result, paciasp and autiasp use different keys,
leading to the crash.
The solution is: if prctl's option is PR_PAC_RESET_KEYS, call real_prctl
directly. This is implemented in assembly, so there are no PAC
instructions involved.
Related issue: https://github.com/android/ndk/issues/1848
```
0000000000095468 <__interceptor_prctl>:
95468: d503233f paciasp
9546c: d10183ff sub sp, sp, #0x60
95470: a90267fe stp x30, x25, [sp, #0x20]
95474: a9035ff8 stp x24, x23, [sp, #0x30]
95478: a90457f6 stp x22, x21, [sp, #0x40]
9547c: a9054ff4 stp x20, x19, [sp, #0x50]
95480: aa1e03f4 mov x20, x30
95484: aa0403f3 mov x19, x4
95488: aa0303f6 mov x22, x3
9548c: aa0203f7 mov x23, x2
95490: aa0103f5 mov x21, x1
95494: 2a0003f8 mov w24, w0
95498: 940172ec bl 0xf2048 <_ZN6__tsan10cur_threadEv>
9549c: 4f05e540 movi v0.16b, #0xaa
954a0: 52801548 mov w8, #0xaa // =170
954a4: aa1403fe mov x30, x20
954a8: 39007fe8 strb w8, [sp, #0x1f]
954ac: aa0003f4 mov x20, x0
954b0: 910043e0 add x0, sp, #0x10
954b4: aa1403e1 mov x1, x20
954b8: bc01b3e0 stur s0, [sp, #0x1b]
954bc: d50320ff xpaclri
954c0: aa1e03e3 mov x3, x30
954c4: 97ffb461 bl 0x82648 <_ZN6__tsan17ScopedInterceptorC2EPNS_11ThreadStateEPKcm>
954c8: 97ff75ea bl 0x72c70 <_ZN11__sanitizer10StackTrace12GetCurrentPcEv>
954cc: 394c2688 ldrb w8, [x20, #0x309]
954d0: 7100051f cmp w8, #0x1
954d4: 540000c1 b.ne 0x954ec <__interceptor_prctl+0x84>
954d8: b9400a88 ldr w8, [x20, #0x8]
954dc: 35000088 cbnz w8, 0x954ec <__interceptor_prctl+0x84>
954e0: 394c2288 ldrb w8, [x20, #0x308]
954e4: 7100051f cmp w8, #0x1
954e8: 54000501 b.ne 0x95588 <__interceptor_prctl+0x120>
954ec: f0001128 adrp x8, 0x2bc000 <_ZN6__tsanL23interceptor_placeholderE+0xcac0>
954f0: 2a1803e0 mov w0, w24
954f4: aa1503e1 mov x1, x21
954f8: f9452508 ldr x8, [x8, #0xa48]
954fc: aa1703e2 mov x2, x23
95500: aa1603e3 mov x3, x22
95504: aa1303e4 mov x4, x19
95508: d63f0100 blr x8
9550c: f9400bf3 ldr x19, [sp, #0x10]
95510: 394c2668 ldrb w8, [x19, #0x309]
95514: 7100051f cmp w8, #0x1
95518: 540002a1 b.ne 0x9556c <__interceptor_prctl+0x104>
9551c: 39406be8 ldrb w8, [sp, #0x1a]
95520: 7100051f cmp w8, #0x1
95524: 54000d60 b.eq 0x956d0 <__interceptor_prctl+0x268>
95528: 394067e8 ldrb w8, [sp, #0x19]
9552c: 7100051f cmp w8, #0x1
95530: 54000de0 b.eq 0x956ec <__interceptor_prctl+0x284>
95534: b9400a68 ldr w8, [x19, #0x8]
95538: 350001a8 cbnz w8, 0x9556c <__interceptor_prctl+0x104>
9553c: b9403268 ldr w8, [x19, #0x30]
95540: 35000e48 cbnz w8, 0x95708 <__interceptor_prctl+0x2a0>
95544: f9400e68 ldr x8, [x19, #0x18]
95548: 91002109 add x9, x8, #0x8
9554c: f27c1d3f tst x9, #0xff0
95550: 54000ec0 b.eq 0x95728 <__interceptor_prctl+0x2c0>
95554: 5280004a mov w10, #0x2 // =2
95558: f900010a str x10, [x8]
9555c: f9000e69 str x9, [x19, #0x18]
95560: f9400a68 ldr x8, [x19, #0x10]
95564: d1002108 sub x8, x8, #0x8
95568: f9000a68 str x8, [x19, #0x10]
9556c: a9454ff4 ldp x20, x19, [sp, #0x50]
95570: a94457f6 ldp x22, x21, [sp, #0x40]
95574: a9435ff8 ldp x24, x23, [sp, #0x30]
95578: a94267fe ldp x30, x25, [sp, #0x20]
9557c: 910183ff add sp, sp, #0x60
95580: d50323bf autiasp
95584: d65f03c0 ret
...
```
Added:
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 2d6cf7fc3282f..a96d325d08983 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1285,8 +1285,34 @@ INTERCEPTOR(int, puts, char *s) {
#endif
#if SANITIZER_INTERCEPT_PRCTL
-INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
- unsigned long arg4, unsigned long arg5) {
+
+# if defined(__aarch64__)
+// https://llvm.org/docs/PointerAuth.html
+// AArch64 is currently the only architecture with full PAC support.
+// Avoid adding PAC instructions to prevent crashes caused by
+// prctl(PR_PAC_RESET_KEYS, ...). Since PR_PAC_RESET_KEYS resets the
+// authentication key, using the old key afterward will lead to a crash.
+
+# if defined(__ARM_FEATURE_BTI_DEFAULT)
+# define BRANCH_PROTECTION_ATTRIBUTE \
+ __attribute__((target("branch-protection=bti")))
+# else
+# define BRANCH_PROTECTION_ATTRIBUTE \
+ __attribute__((target("branch-protection=none")))
+# endif
+
+# define PRCTL_INTERCEPTOR(ret_type, func, ...) \
+ DEFINE_REAL(ret_type, func, __VA_ARGS__) \
+ DECLARE_WRAPPER(ret_type, func, __VA_ARGS__) \
+ extern "C" INTERCEPTOR_ATTRIBUTE BRANCH_PROTECTION_ATTRIBUTE ret_type \
+ WRAP(func)(__VA_ARGS__)
+
+# else
+# define PRCTL_INTERCEPTOR INTERCEPTOR
+# endif
+
+PRCTL_INTERCEPTOR(int, prctl, int option, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4, unsigned long arg5) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
static const int PR_SET_NAME = 15;
@@ -1326,7 +1352,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
}
return res;
}
-#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
+# define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
#else
#define INIT_PRCTL
#endif // SANITIZER_INTERCEPT_PRCTL
More information about the llvm-commits
mailing list