89 lines
3.4 KiB
Plaintext
89 lines
3.4 KiB
Plaintext
Pointer authentication in AArch64 Linux
|
|
=======================================
|
|
|
|
Author: Mark Rutland <mark.rutland@arm.com>
|
|
Date: 2017-07-19
|
|
|
|
This document briefly describes the provision of pointer authentication
|
|
functionality in AArch64 Linux.
|
|
|
|
|
|
Architecture overview
|
|
---------------------
|
|
|
|
The ARMv8.3 Pointer Authentication extension adds primitives that can be
|
|
used to mitigate certain classes of attack where an attacker can corrupt
|
|
the contents of some memory (e.g. the stack).
|
|
|
|
The extension uses a Pointer Authentication Code (PAC) to determine
|
|
whether pointers have been modified unexpectedly. A PAC is derived from
|
|
a pointer, another value (such as the stack pointer), and a secret key
|
|
held in system registers.
|
|
|
|
The extension adds instructions to insert a valid PAC into a pointer,
|
|
and to verify/remove the PAC from a pointer. The PAC occupies a number
|
|
of high-order bits of the pointer, which varies dependent on the
|
|
configured virtual address size and whether pointer tagging is in use.
|
|
|
|
A subset of these instructions have been allocated from the HINT
|
|
encoding space. In the absence of the extension (or when disabled),
|
|
these instructions behave as NOPs. Applications and libraries using
|
|
these instructions operate correctly regardless of the presence of the
|
|
extension.
|
|
|
|
The extension provides five separate keys to generate PACs - two for
|
|
instruction addresses (APIAKey, APIBKey), two for data addresses
|
|
(APDAKey, APDBKey), and one for generic authentication (APGAKey).
|
|
|
|
|
|
Basic support
|
|
-------------
|
|
|
|
When CONFIG_ARM64_PTR_AUTH is selected, and relevant HW support is
|
|
present, the kernel will assign random key values to each process at
|
|
exec*() time. The keys are shared by all threads within the process, and
|
|
are preserved across fork().
|
|
|
|
Presence of address authentication functionality is advertised via
|
|
HWCAP_PACA, and generic authentication functionality via HWCAP_PACG.
|
|
|
|
The number of bits that the PAC occupies in a pointer is 55 minus the
|
|
virtual address size configured by the kernel. For example, with a
|
|
virtual address size of 48, the PAC is 7 bits wide.
|
|
|
|
Recent versions of GCC can compile code with APIAKey-based return
|
|
address protection when passed the -msign-return-address option. This
|
|
uses instructions in the HINT space (unless -march=armv8.3-a or higher
|
|
is also passed), and such code can run on systems without the pointer
|
|
authentication extension.
|
|
|
|
In addition to exec(), keys can also be reinitialized to random values
|
|
using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY,
|
|
PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEY
|
|
specifies which keys are to be reinitialized; specifying 0 means "all
|
|
keys".
|
|
|
|
|
|
Debugging
|
|
---------
|
|
|
|
When CONFIG_ARM64_PTR_AUTH is selected, and HW support for address
|
|
authentication is present, the kernel will expose the position of TTBR0
|
|
PAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), which
|
|
userspace can acquire via PTRACE_GETREGSET.
|
|
|
|
The regset is exposed only when HWCAP_PACA is set. Separate masks are
|
|
exposed for data pointers and instruction pointers, as the set of PAC
|
|
bits can vary between the two. Note that the masks apply to TTBR0
|
|
addresses, and are not valid to apply to TTBR1 addresses (e.g. kernel
|
|
pointers).
|
|
|
|
|
|
Virtualization
|
|
--------------
|
|
|
|
Pointer authentication is not currently supported in KVM guests. KVM
|
|
will mask the feature bits from ID_AA64ISAR1_EL1, and attempted use of
|
|
the feature will result in an UNDEFINED exception being injected into
|
|
the guest.
|