Hello,I am running some dummy aarch64 ELF I have built using clang with -mbranch-protection=pac-ret+leaf+b-key.
qemu successfully emulates the code, however the pointer authentication signature seems weird to me: only one byte is used for the signature. Here is an example:
FE 07 C1 DA PACIB X30, SP Before the LR gets signed, its value is 0x00000000FEFDD99C. After being signed by PACIB, its value is 0x00610000FEFDD99C.If I disable BTI, the signature takes 2 bytes, which is "better". However on real aarch64 system (like Apple M1 chips), the signature uses the remaining bytes.
In both cases (with or without BTI), the signature is not honored: if I manually strip the signature or change it using gdb, the RETAB instruction does not change the LR for generating a fault, which should be the right behavior.
I have explored the qemu source code, and I guess the following code is responsible for adding the signature to the pointer:
target/arm/pauth_helper.c: ----------------------------------------------------------------------static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier, ARMPACKey *key, bool data) {
... top_bit = 64 - 8 * param.tbi; bot_bit = 64 - param.tsz; ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext); ----------------------------------------------------------------------We notice how BTI reduces the size of the signature, and how tsz is reducing it too.
So, my question is how can we manipulate TCR from qemu-user, in order to change tsz, so we can store the signature on more bytes ?
I am running qemu from the git branch stable-6.0, using 16K page. My host is an 86_64 host, running archlinux. Here is how I launch aarch64 qemu-user:
~/git/qemu/build/qemu-aarch64 -L /usr/aarch64-linux-gnu -p 16K -g 1234 build/test_pac_no_bti
Regards, -zadig
OpenPGP_signature
Description: OpenPGP digital signature