Status of the PAC implementation

Good morning,
I was looking at the Pointer Authentication page on the documentation since i’m interested in exploring the current support for the feature.

I manually tried to add the ptrauth operand bundle to the IR like it’s shown in the documentation

define void @f(void ()* %fp) {
  call void %fp() [ "ptrauth"(i32 <key>, i64 <data>) ]
  ret void
}

This is what i’m currently trying

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @f(ptr noundef %0) #0 {
  %2 = alloca ptr, align 8
  store ptr %0, ptr %2, align 8
  %3 = load ptr, ptr %2, align 8
  call void %3() [ "ptrauth" (i32 10, i64 1234) ]
  ret void
}

The problem i’m facing is that despite the fact that in the documentation it says that the intrinsic maps directly to the PAC and AUT instruction, when i run llc on the IR the resulting assembly doesn’t have any trace of those instructions.
For reference, this is the assembly generated

f:                                      // @f
  .cfi_startproc
// %bb.0:
  paciasp
  .cfi_negate_ra_state
  sub  sp, sp, #32
  .cfi_def_cfa_offset 32
  stp  x29, x30, [sp, #16]             // 16-byte Folded Spill
  add  x29, sp, #16
  .cfi_def_cfa w29, 16
  .cfi_offset w30, -8
  .cfi_offset w29, -16
  str  x0, [sp, #8]
  ldr  x8, [sp, #8]
  blr  x8
  .cfi_def_cfa wsp, 32
  ldp  x29, x30, [sp, #16]             // 16-byte Folded Reload
  add  sp, sp, #32
  .cfi_def_cfa_offset 0
  .cfi_restore w30
  .cfi_restore w29
  retaa

What am i missing?

Tagging @ahmedbougacha

This was only recently implemented in [AArch64][PAC] Lower direct authenticated calls to ptrauth constants. by ahmedbougacha · Pull Request #97664 · llvm/llvm-project · GitHub

Overall, pauth support in LLVM mainline is WIP. Some functionality might appear in LLVM 19

Thank you very much for the answer!

So if i understand it correctly, if i’m interested in the CFI enforcing features my only option at the moment is to compile a program with the -mbranch-protection=pac-ret+leaf+b-key flag (that only works if the target is arm v8.3).

What it does is it adds through a MachineFunctionPass the paciasp instruction after the function preamble and the retaa/retab instruction before the function epilogue (this signing tho doesn’t offer any protection for jump oriented programming).

Did i understand everything correctly?
Sorry in advance if i misunderstood something

Well, pac-ret only protects back edges (return address), for complete pauth you’d also need a frontend support as it is a separate ABI. And full pauth is currently WIP in LLVM.

If you also want a level of protection against jump oriented programming, you can use -mbranch-protection=bti or -mbranch-protection=standard (to have both pac-ret and bti). Some more info about BTI can be found in various places, including https://llsoftsec.github.io/llsoftsecbook/#bti.