qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: qemu-user aarch64 and pointer authentication


From: Peter Maydell
Subject: Re: qemu-user aarch64 and pointer authentication
Date: Tue, 11 Jan 2022 15:57:53 +0000

On Tue, 11 Jan 2022 at 15:28, zadig <zadig@qbool.fr> wrote:
>
> 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.

The architecture specifies that the number of bits used for the
signature depends on various properties of the CPU and of
the configuration that the host OS has put it into.

> 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.

That probably indicates that that specific system happens to
configure the CPU differently. (For instance, I think the
M1 has a different implemented address space size.)
7 bits of signature would be expected for a CPU with TBI (top-byte-ignore)
enabled and a 48-bit virtual-address size.

> 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.

This sounds like a bug -- can you provide a repro case ?
Also, if you could confirm that this still happens on a
QEMU built from current git that would be helpful.

(We do have some test cases for pauth -- see tests/tcg/aarch64/pauth*.c --
but it looks like they only test against the aut* instructions, not
against retab.)

> 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 ?

You can't change TCR from usermode, because it's a privileged
register. What you get is what QEMU sets it as, which in theory
should be the value that a real Linux kernel would set it to
for the kind of CPU that is being emulated. Looking at the code
I'm not sure if we're setting TCR the same way the kernel does:
to confirm that we'd need to look at the kernel source code and
cross-check what values it uses.

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]