[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