Reputation: 321
I am experiencing a strange behavior of the clang compiler flag -mbranch-protection=pac-ret+bti
. By looking into the documentation, the intended behavior appears to generate both PAC (paciasp)
as well as BTI
instructions. I am seeing paciasp
instruction but not the BTI
instruction in the assembly when compiling with -mbranch-protection=pac-ret+bti
.
When compiling with -mbranch-protection=bti
, the BTI
instruction is being generated at the start of the function marking the valid entry point in a function as it should be.
This seems a bit unusual. PAC
protects from ROP attacks, while BTI
protects from JOP attacks. Is this a bug in the implementation? Any further clarification will be appreciated.
Note that BTI
is supported from armv8.5-a
and PAC
from armv8.3-a
onwards. The compiler will generate nop
for the previous architectures. Clang version 12.0 is used in the test.
Simple Code Example (test.c):
#include<stdio.h>
int main(int argc, char** argv){
printf("%s", "Hello Main!");
}
Compilation with PAC+BTI:
$ clang -S -mbranch-protection=pac-ret+bti -arch arm64e -march=armv8.7-a -o test.s test.c
Output:
main:
paciasp
-----
-----
-----
retaa
Note: No BTI instruction generated in this case.
Compilation with BTI:
clang -S -mbranch-protection=bti -arch arm64e -march=armv8.7-a -o test.s test.c
Output:
main:
bti c
-----
-----
-----
Upvotes: 2
Views: 564
Reputation: 11
When activating PAC with BTI, paciasp instruction serves also as a landing pad (BTI-like). This is an optimization that is done by ARM to save one extra instruction. No bugs.
Upvotes: 1