[clang] [llvm] [LFI][X86] Add X86 LFI target and system instruction rewrites (PR #189569)
Zachary Yedidia via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 9 17:40:33 PDT 2026
================
@@ -240,73 +289,178 @@ before moving it back into ``sp`` with a safe ``add``.
Link register modification
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When the link register is modified, we write the modified value to a
-temporary, before loading it back into ``x30`` with a safe ``add``.
-
-+-----------------------+----------------------------+
-| Original | Rewritten |
-+-----------------------+----------------------------+
-| .. code-block:: | .. code-block:: |
-| | |
-| ldr x30, [...] | ldr x26, [...] |
-| | add x30, x27, w26, uxtw |
-| | |
-+-----------------------+----------------------------+
-| .. code-block:: | .. code-block:: |
-| | |
-| ldp xN, x30, [...] | ldp xN, x26, [...] |
-| | add x30, x27, w26, uxtw |
-| | |
-+-----------------------+----------------------------+
-| .. code-block:: | .. code-block:: |
-| | |
-| ldp x30, xN, [...] | ldp x26, xN, [...] |
-| | add x30, x27, w26, uxtw |
-| | |
-+-----------------------+----------------------------+
+When the link register is modified, the guard is deferred until the next
+control flow instruction. This approach maintains compatibility with Pointer
+Authentication Code (PAC) instructions by keeping signed pointers intact until
+they are needed for control flow. The guard uses ``x30`` as both the source and
+destination (``add x30, x27, w30, uxtw``).
+
++---------------------------+-------------------------------+
+| Original | Rewritten |
++---------------------------+-------------------------------+
+| .. code-block:: | .. code-block:: |
+| | |
+| ldr x30, [...] | ldr x30, [...] |
+| ret | add x30, x27, w30, uxtw |
+| | ret |
+| | |
++---------------------------+-------------------------------+
+| .. code-block:: | .. code-block:: |
+| | |
+| ldp xN, x30, [...] | ldp xN, x30, [...] |
+| ret | add x30, x27, w30, uxtw |
+| | ret |
+| | |
++---------------------------+-------------------------------+
+
+Pointer Authentication Code (PAC) support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LFI is designed to be compatible with ARM Pointer Authentication Code (PAC)
+instructions. PAC signs and authenticates pointers (typically the return
+address in ``x30``) to protect against control-flow hijacking attacks.
+
+To get the security benefits of PAC with LFI-compiled code, the hardware must
+support **FEAT_FPAC** (Faulting PAC), which causes authentication failures to
+immediately fault. Without FEAT_FPAC, a failed authentication produces a
+"poisoned" pointer that only faults when dereferenced, which may not provide
+immediate detection of authentication failures.
+
+**PACIASP** (sign return address) passes through unchanged. It signs the
+current value of ``x30`` using the stack pointer as a modifier, which does not
+affect LFI's security guarantees.
----------------
zyedidia wrote:
Yes these changes are due to some stacking. I've removed the main AArch64 doc changes in this PR. There's still a bit of overlap in the doc changes between this PR and the AArch64 PR -- when one of them is merged I'll rebase the other one to fix that up.
https://github.com/llvm/llvm-project/pull/189569
More information about the cfe-commits
mailing list