Diagnosing ARM64 Pointer Authentication Faults: SIGSEGV on Signed Pointers
Step‑by‑step guide to diagnose ARM64 Pointer Authentication faults: check SCTLR_EL1, read PAC keys, inspect ESR/FAR, verify with a test program, and apply the appropriate fix.
04 Sept 2026, 15:58 UTC

Recognizable condition
A process suddenly crashes with SIGSEGV or an illegal‑instruction exception when it executes code that uses signed pointers (e.g., after loading a shared library, JIT‑compiled code, or returning from a signal handler). The fault often occurs on instructions such as AUTIASP, AUTIAZ, AUTDASP or AUTDAZ.
Cause / diagnostic table
| Observed symptom | Likely cause |
|---|---|
Fault address points to an AUT* instruction; ESR_EL1 shows ISS[24:0] = 0x0 (Pointer Authentication failure) | PAC key mismatch or corrupted pointer |
| Same fault after a context switch or thread migration | PAC keys not restored correctly (APIAKey/APIBKey) |
| Fault occurs even though the code never uses PAC instructions | PAC disabled in SCTLR_EL1 leading to silent corruption that later triggers a fault |
Pointer value is not 16‑byte aligned when used with AUT* | Mis‑aligned pointer causes authentication failure |
Ordered checks
Verify that Pointer Authentication is enabled for the current exception level.
# Run at EL1 (kernel) or EL0 (userspace) with sufficient privilege to read system registers # Example for EL1 (requires root or CAP_SYS_RAWIO) mrs x0, SCTLR_EL1 # Check bits: EnIA (bit 2), EnIB (bit 3), EnDA (bit 10), EnDB (bit 11) # If any of these bits are 0, PAC is disabled for that instruction type.Permissions: Root or a process with
CAP_SYS_RAWIO(EL1) or running under a debugger with access to system registers (EL0). Risk: Reading registers is safe; no state change.Read the PAC key registers to see whether they hold the expected values.
# APIAKeyLo/Hi and APIBKeyLo/Hi (EL1) mrs x0, APIAKeyLo_EL1 # x0 = low 64 bits of APIAKey mrs x1, APIAKeyHi_EL1 # x1 = high 64 bits of APIAKey mrs x2, APIBKeyLo_EL1 mrs x3, APIBKeyHi_EL1 # Compare x0/x1/x2/x3 with the values known from the OS key‑management routine.Permissions: Same as step 1. Risk: None.
Examine the fault information captured in ESR_EL1 (or the userspace signal context).
# From a signal handler or kernel oops dump: mrs x0, ESR_EL1 # Extract ISS[24:0] (bits 0‑24) – if non‑zero indicates a PAC failure. # Also read FAR_EL1 to see the faulting address. mrs x1, FAR_EL1Permissions: Access to the fault context (kernel log,
dmesg, or userspacesigactionwithSA_SIGINFO). Risk: None.Run a software PAC verification routine on a known‑good signed pointer.
/* Compile with -mbranch-protection=pac-ret+leaf (or equivalent) */ #include #include #include uint64_t sign_ptr(uint64_t ptr, uint64_t key_lo, uint64_t key_hi) { uint64_t signed_ptr; __asm__ volatile ("autiasp %0, %1, %2" : "=r" (signed_ptr) : "r" (ptr), "r" (key_lo), "r" (key_hi)); return signed_ptr; } int main(void) { uint64_t key_lo = 0x; /* replace with value from step 2 */ uint64_t key_hi = 0x; uint64_t ptr = (uint64_t)main; /* any code pointer */ uint64_t signed_ptr = sign_ptr(ptr, key_lo, key_hi); /* Now authenticate – should not fault if keys match */ __asm__ volatile ("autiasp %0, %0, %1" : : "r" (signed_ptr), "r" (key_lo) : "cc"); printf("PAC verification succeeded\n"); return 0; }Where to run: Userspace, compiled for AArch64. Permissions: None beyond normal execution. Risk: If keys are wrong the program will fault with
SIGSEGV; this is expected and helps confirm the mismatch.
Fixes tied to findings
If any of the
EnIA/EnIB/EnDA/EnDBbits inSCTLR_EL1are cleared, set them:mrs x0, SCTLR_EL1 orr x0, x0, #(1 << 2) /* EnIA */ orr x0, x0, #(1 << 3) /* EnIB */ orr x0, x0, #(1 << 10) /* EnDA */ orr x0, x0, #(1 << 11) /* EnDB */ msr SCTLR_EL1, x0 isb /* synchronize */Permissions: EL2/EL3 or a kernel module with write access to system registers. Risk: Enabling PAC may expose bugs in code that incorrectly signs pointers; test on a non‑production core first.
If the PAC keys read in step 2 do not match the OS‑maintained values, restore them after a context switch:
# Assuming the correct keys are stored in variables correct_lo/hi msr APIAKeyLo_EL1, correct_lo msr APIAKeyHi_EL1, correct_hi msr APIBKeyLo_EL1, correct_lo /* many OSes use same key for A & B */ msr APIBKeyHi_EL1, correct_hi isbPermissions: Privileged (EL2/EL3). Risk: Incorrect key values will cause immediate PAC faults on any signed pointer use.
Recompile or regenerate the offending code with proper signing:
- For userspace:
gcc -mbranch-protection=pac-ret+leaf -o prog prog.c - For JIT: ensure the code‑emitter calls the platform’s PAC signing routine before emitting
AUT*instructions.
Permissions: Normal build environment. Risk: None beyond normal compilation.
- For userspace:
Replace corrupted pointers (e.g., reload the library, refresh function pointers).
Permissions: Same as the application. Risk: None.
If the fault persists on a specific core after the above steps, isolate that core and run the ARM PAC self‑test (if available) to check for hardware defect.
# Example using a kernel self‑test module (requires CONFIG_ARM64_PAC_SELFTEST) echo 1 > /sys/devices/system/cpu/cpuX/pac_self_test # Check dmesg for pass/fail.Permissions: Root. Risk: Test may temporarily disable PAC on the core while running.
Escalation criteria
- Pointer Authentication faults continue on multiple cores after verifying SCTLR_EL1 bits and restoring keys.
- The software verification routine (step 4) fails even when using keys known to be correct from the OS key‑management source.
- Kernel logs show recurrent
PAC faultESR codes with varying fault addresses, suggesting systematic key corruption. - Hardware self‑test reports failure on a core.
When any of the above occurs, escalate to the platform vendor or silicon provider with the collected ESR_EL1, FAR_EL1, SCTLR_EL1, and PAC key register values.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.