a83427f2
by Martin Storsjö at 2026-06-15T22:14:44+02:00
ntdll: Don't validate arm64 pointer signing when unwinding.
When unwinding through a "pac_sign_lr" opcode, we need to strip
out pointer authentication bits from the address in the LR
register.
Previously this was done with the "autib1716" instruction, which
does validate that the address in x17 is properly signed with
the B key, given the reference address in x16 (SP).
However - Clang has a bug [1] since Clang 19, that has caused it to
generate incorrect prologues (if building with
"-mbranch-protection=standard"), doing return address signing using
the A key, while the unwind info says that the address should be
signed using the B key. (The unwind info has no way of signaling
which key to use, but the normative form uses the B key.)
It also turns out that Windows doesn't do any validation of the
signing of the return address when unwinding; Windows can
correctly execute and do unwinding in binaries built with the
buggy Clang - which might explain why the bug has passed unnoticed
for so long.
Therefore, doing the same and reducing the strictness here in Wine
seems reasonable (in addition to doing it to work around the Clang
bug).
By using "xpaclri" instead of "autib1716", we strip out the
authentication bits without validating them. Both instructions can
be encoded as plain hint instructions, that are treated as nop
instructions for older CPUs.
In addition to failing on unwinding in user binaries built return
address signing (e.g. "-mbranch-protection=standard") with a buggy
Clang, this issue also hits cases if Wine itself has been built with
"-mbranch-protection=standard" in CROSSCFLAGS, with a buggy version
of Clang. This is the case on e.g. Ubuntu 26.04, making those
builds of Wine fail (either directly on startup, or failing only
if attempting to do unwinding in user code), if running on a CPU that
supports pointer authentication.
[1] https://github.com/llvm/llvm-project/issues/203852