Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring arm64e/ptrauth support to parity with main upstreaming branch #8946

Open
wants to merge 58 commits into
base: next
Choose a base branch
from

Conversation

ahmedbougacha
Copy link

No description provided.

ahmedbougacha and others added 30 commits July 3, 2024 11:08
Try to optimize a call to the result of a ptrauth intrinsic, potentially
into the ptrauth call bundle:
- call(ptrauth.resign(p)), ["ptrauth"()] ->  call p, ["ptrauth"()]
- call(ptrauth.sign(p)),   ["ptrauth"()] ->  call p
- call(ptrauth.auth(p))                  ->  call p, ["ptrauth"()]
as long as the key/discriminator are the same in sign and auth-bundle.

This relaxes the existing combine in one major way: it can generate calls
with ptrauth bundles with a different key from the existing call.
Without knowledge of the target keys, this may be unsound.

Generating a plain call to a raw unauthenticated pointer is generally
undesirable, but if we ended up seeing a naked ptrauth.sign in the first
place, we already have suspicious code.  Unauthenticated calls are also
easier to spot than naked signs, so let the indirect call shine.
Try to optimize a call to a ptrauth constant, into its ptrauth bundle:
  call(ptrauth(f)), ["ptrauth"()] ->  call f
as long as the key/discriminator are the same in constant and bundle.
This introduces 3 hardening modes in the authentication step of
auth/resign lowering:
- unchecked, which uses the AUT instructions as-is
- poison, which detects authentication failure (using an XPAC+CMP
  sequence), explicitly yielding the XPAC result rather than the
  AUT result, to avoid leaking
- trap, which additionally traps on authentication failure,
  using BRK #0xC470 + key (IA C470, IB C471, DA C472, DB C473.)

Not all modes are necessarily useful in all contexts, and there
are more performant alternative lowerings in specific contexts
(e.g., when I/D TBI enablement is a target ABI guarantee.)

This is controlled by the `ptrauth-auth-traps` function attributes,
and can be overridden using `-aarch64-ptrauth-auth-checks=`.
When the FPAC feature is present, we can rely on its faulting
behavior to avoid emitting the expensive authentication failure
check sequence ourvelves.  In which case we emit the same
sequence as a plain unchecked auth/resign.
This removes x16/x17 from tcGPR64, to use them for the check sequence.
That further triggers a change in synthesized regclasses, and both that
and tcGPR64 in turn cause various regalloc changes.
Used for lowering some code refs to ptrauth constants.
This was the last one of the ExpandHardenedPseudos, as it's
now done in AsmPrinter.  The original LOH use-case can now be
replaced with late LOH emission from within AsmPrinter itself.
This includes a new pseudo-instruction, XPACIuntied, to be used when
lowering @llvm.returnaddress: it avoids clobbering LR, thereby saving
a stack frame when it's not otherwise needed.
Give users an option to sign a function pointer using a non-zero
discrimiantor based on the type of the destination.

Co-authored-by: John McCall <[email protected]>
With signed null, signed uintptr and isa pointer support.
__cxa_throw is declared to take its destructor as void (*)(void *). We
must match that if function pointers can be authenticated with
a discriminator based on their type.
Enabled in clang using:
  -fptrauth-indirect-gotos

and at the IR level using function attribute:
  "ptrauth-indirect-gotos"

Signing uses IA and a per-function integer discriminator.
The discriminator isn't ABI-visible, and is currently:
  ptrauth_string_discriminator("<function_name> blockaddress")

A sufficiently sophisticated frontend could benefit from
per-indirectbr discrimination, which would need additional
machinery, such as allowing "ptrauth" bundles on indirectbr.
For our purposes, the simple scheme above is sufficient.
I couldn't find users after all, including in lldb.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants