llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.08k stars 11.1k forks source link

[PAC][AArch64] Unify LR signing implementations #98054

Open kovdan01 opened 1 week ago

kovdan01 commented 1 week ago

Currently, two LR signing implementations exist:

  1. One enabled with -mbranch-protection=pac-ret[+b-key|+leaf|+pc]*. This is present in current mainline llvm. Details: a)sign-return-address llvm module flag is set (and optionally sign-return-address-all with +leaf); b) PAUTH_PROLOGUE and PAUTH_EPILOGUE pseudo-instructions are emitted in AArch64FrameLowering::emitPrologue and AArch64FrameLowering::emitEpilogue; these pseudos are later expanded by AArch64PointerAuth pass; c) both A and B keys can be used (depending on +b-key and corresponding function attribute sign-return-address-key or module flag sign-return-address-with-bkey); d) using pc register as additional modifier is supported with +pc (corresponding module flag is branch-protection-pauth-lr).

  2. One enabled with -fptrauth-returns. This is present in Apple downstream and is a subject for upstreaming. a) ptrauth-returns attribute is set on functions we want this to be enabled; b) actual codegen logic is implemented in AArch64FrameLowering::emitPrologue and AArch64FrameLowering::emitEpilogue - we emit actual instructions like pacibsp directly there; c) B key is always used; d) using pc register as additional modifier is not supported.

See also https://github.com/llvm/llvm-project/pull/97237#discussion_r1666090234

TODO:

  1. Ensure if fptrauth-returns is equal to -mbranch-protection=pac-ret+b-key. Several downstream patches are subject for investigation here: a) https://github.com/ahmedbougacha/llvm-project/commit/c84e3837e017cf1335405855b73b2ccd2754a263 b) https://github.com/ahmedbougacha/llvm-project/commit/252558afa626a700770b77dd629bd0b0ca575027

    If there is downstream functionality present for -fptrauth-returns in downstream but not present for -mbranch-protection=pac-ret in mainline - upstream that.

  2. Make upstream generate code equal to downstream when -fptrauth-returns is passed without bringing the second implementation to mainline. Only present mainline implementation should be left in terms of codegen, probably with some additions (see previous point). Possible ways to do that:

    a) set "sign-return-address" and "sign-return-address-with-bkey" function attributes when -fptrauth-returns is passed; b) set "ptrauth-returns" function attribute (like in downstream and similar to other attributes like "ptrauth-calls", "ptrauth-auth-traps", etc) and add a check against that near existing checks against "sign-return-address" and "sign-return-address-with-bkey".

  3. Support -mbranch-protection=pauthabi+pac-ret+b-key. Since pac-ret+b-key should do the same thing as -fptrauth-returns, it's a subset of pauthabi, so no reason for not supporting that. As for now, we explicitly do not support that (see #97237)

kovdan01 commented 1 week ago

Tagging @asl

llvmbot commented 1 week ago

@llvm/issue-subscribers-backend-aarch64

Author: Daniil Kovalev (kovdan01)

Currently, two LR signing implementations exist: 1. One enabled with `-mbranch-protection=pac-ret[+b-key|+leaf|+pc]*`. This is present in current mainline llvm. Details: a)`sign-return-address` llvm module flag is set (and optionally `sign-return-address-all` with `+leaf`); b) `PAUTH_PROLOGUE` and `PAUTH_EPILOGUE` pseudo-instructions are emitted in `AArch64FrameLowering::emitPrologue` and `AArch64FrameLowering::emitEpilogue`; these pseudos are later expanded by `AArch64PointerAuth` pass; c) both A and B keys can be used (depending on `+b-key` and corresponding function attribute `sign-return-address-key` or module flag `sign-return-address-with-bkey`); d) using `pc` register as additional modifier is supported with `+pc` (corresponding module flag is `branch-protection-pauth-lr`). 2. One enabled with `-fptrauth-returns`. This is present in Apple downstream and is a subject for upstreaming. a) `ptrauth-returns` attribute is set on functions we want this to be enabled; b) actual codegen logic is implemented in `AArch64FrameLowering::emitPrologue` and `AArch64FrameLowering::emitEpilogue` - we emit actual instructions like `pacibsp` directly there; c) B key is always used; d) using `pc` register as additional modifier is **not** supported. See also https://github.com/llvm/llvm-project/pull/97237#discussion_r1666090234 TODO: 1. Ensure if `fptrauth-returns` is equal to `-mbranch-protection=pac-ret+b-key`. Several downstream patches are subject for investigation here: a) https://github.com/ahmedbougacha/llvm-project/commit/c84e3837e017cf1335405855b73b2ccd2754a263 b) https://github.com/ahmedbougacha/llvm-project/commit/252558afa626a700770b77dd629bd0b0ca575027 If there is downstream functionality present for `-fptrauth-returns` in downstream but not present for `-mbranch-protection=pac-ret` in mainline - upstream that. 2. Make upstream generate code equal to downstream when `-fptrauth-returns` is passed without bringing the second implementation to mainline. Only present mainline implementation should be left in terms of codegen, probably with some additions (see previous point). Possible ways to do that: a) set "sign-return-address" and "sign-return-address-with-bkey" function attributes when `-fptrauth-returns` is passed; b) set "ptrauth-returns" function attribute (like in downstream and similar to other attributes like "ptrauth-calls", "ptrauth-auth-traps", etc) and add a check against that near existing checks against "sign-return-address" and "sign-return-address-with-bkey". 3. Support `-mbranch-protection=pauthabi+pac-ret+b-key`. Since `pac-ret+b-key` should do the same thing as `-fptrauth-returns`, it's a subset of `pauthabi`, so no reason for not supporting that. As for now, we explicitly do not support that (see #97237)