Enable Pointer Authentication Codes (PAC) and Branch Target
Identification (BTI) support for ARM 64 targets.
OpenH264 does not require any of the PAC signing and verification as the
leaf functions do not store x30 to the stack. Also, no indirect branches
are performed so no need to annotate branch targets with bti j landing
pad instructions. The only thing required is to label the function entry
points with bti c instructions and ensure the GNU Notes are updated for
their respective features when enabled for ELF files.
A detailed summary on how PAC and BTI work are provided below for
clarity.
PAC works by signing the LR with either an A key or B key and verifying
the return address. There are quite a few instructions capable of doing
this, however, the Linux ARM ABI is to use hint compatible instructions
that can be safely NOP'd on older hardware and can be assembled and
linked with older binutils. This limits the instruction set to paciasp,
pacibsp, autiasp and autibsp. Instructions prefixed with pac are for
signing and instructions prefixed with aut are for signing. Both
instructions are then followed with an a or b to indicate which signing
key they are using. The keys can be controlled using
-mbranch-protection=pac-ret for the A key and
-mbranch-protection=pac-ret+b-key for the B key.
BTI works by marking all indirect call and jump positions with bti c
and bti j instructions respectively. If execution control transfers
to an instruction other than a BTI instruction, the execution is
killed via SIGILL. Note that to remove one instruction, the
aforementioned pac instructions will also work as a BTI landing pad
for bti c usages.
For BTI to work, all object files linked for a unit of execution,
whether an executable or a library must have the GNU Notes section of
the ELF file marked to indicate BTI support. This is so loader/linkers
can apply the proper permission bits (PROT_BRI) on the memory region.
PAC can also be annotated in the GNU ELF notes section, but it's not
required for enablement, as interleaved PAC and non-pac code works as
expected since it's the callee that performs all the checking.
Testing was done under the following CFLAGS and CXXFLAGS for all
combinations:
1. -mbranch-protection=none
2. -mbranch-protection=standard
3. -mbranch-protection=pac-ret
4. -mbranch-protection=pac-ret+b-key
5. -mbranch-protection=bti
Signed-off-by: Bill Roberts <[email protected]>