Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
6.1 kB · 142 lines
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143=======================================Pointer authentication in AArch64 Linux=======================================
Author: Mark Rutland <mark.rutland@arm.com>
Date: 2017-07-19
This document briefly describes the provision of pointer authenticationfunctionality in AArch64 Linux.
Architecture overview---------------------
The ARMv8.3 Pointer Authentication extension adds primitives that can beused to mitigate certain classes of attack where an attacker can corruptthe contents of some memory (e.g. the stack).
The extension uses a Pointer Authentication Code (PAC) to determinewhether pointers have been modified unexpectedly. A PAC is derived froma pointer, another value (such as the stack pointer), and a secret keyheld 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 numberof high-order bits of the pointer, which varies dependent on theconfigured virtual address size and whether pointer tagging is in use.
A subset of these instructions have been allocated from the HINTencoding space. In the absence of the extension (or when disabled),these instructions behave as NOPs. Applications and libraries usingthese instructions operate correctly regardless of the presence of theextension.
The extension provides five separate keys to generate PACs - two forinstruction 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 ispresent, the kernel will assign random key values to each process atexec*() time. The keys are shared by all threads within the process, andare preserved across fork().
Presence of address authentication functionality is advertised viaHWCAP_PACA, and generic authentication functionality via HWCAP_PACG.
The number of bits that the PAC occupies in a pointer is 55 minus thevirtual address size configured by the kernel. For example, with avirtual address size of 48, the PAC is 7 bits wide.
When ARM64_PTR_AUTH_KERNEL is selected, the kernel will be compiledwith HINT space pointer authentication instructions protectingfunction returns. Kernels built with this option will work on hardwarewith or without pointer authentication support.
In addition to exec(), keys can also be reinitialized to random valuesusing the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY,PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEYspecifies which keys are to be reinitialized; specifying 0 means "allkeys".
Debugging---------
When CONFIG_ARM64_PTR_AUTH is selected, and HW support for addressauthentication is present, the kernel will expose the position of TTBR0PAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), whichuserspace can acquire via PTRACE_GETREGSET.
The regset is exposed only when HWCAP_PACA is set. Separate masks areexposed for data pointers and instruction pointers, as the set of PACbits can vary between the two. Note that the masks apply to TTBR0addresses, and are not valid to apply to TTBR1 addresses (e.g. kernelpointers).
Additionally, when CONFIG_CHECKPOINT_RESTORE is also set, the kernelwill expose the NT_ARM_PACA_KEYS and NT_ARM_PACG_KEYS regsets (structuser_pac_address_keys and struct user_pac_generic_keys). These can beused to get and set the keys for a thread.
Virtualization--------------
Pointer authentication is enabled in KVM guest when each virtual cpu isinitialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] andrequesting these two separate cpu features to be enabled. The current KVMguest implementation works by enabling both features together, so boththese userspace flags are checked before enabling pointer authentication.The separate userspace flag will allow to have no userspace ABI changesif support is added in the future to allow these two features to beenabled independently of one another.
As Arm Architecture specifies that Pointer Authentication feature isimplemented along with the VHE feature so KVM arm64 ptrauth code relieson VHE mode to be present.
Additionally, when these vcpu feature flags are not set then KVM willfilter out the Pointer Authentication system key registers fromKVM_GET/SET_REG_* ioctls and mask those features from cpufeature IDregister. Any attempt to use the Pointer Authentication instructions willresult in an UNDEFINED exception being injected into the guest.
Enabling and disabling keys---------------------------
The prctl PR_PAC_SET_ENABLED_KEYS allows the user program to control whichPAC keys are enabled in a particular task. It takes two arguments, thefirst being a bitmask of PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEYand PR_PAC_APDBKEY specifying which keys shall be affected by this prctl,and the second being a bitmask of the same bits specifying whether the keyshould be enabled or disabled. For example::
prctl(PR_PAC_SET_ENABLED_KEYS, PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY, PR_PAC_APIBKEY, 0, 0);
disables all keys except the IB key.
The main reason why this is useful is to enable a userspace ABI that uses PACinstructions to sign and authenticate function pointers and other pointersexposed outside of the function, while still allowing binaries conforming tothe ABI to interoperate with legacy binaries that do not sign or authenticatepointers.
The idea is that a dynamic loader or early startup code would issue thisprctl very early after establishing that a process may load legacy binaries,but before executing any PAC instructions.
For compatibility with previous kernel versions, processes start up with IA,IB, DA and DB enabled, and are reset to this state on exec(). Processes createdvia fork() and clone() inherit the key enabled state from the calling process.
It is recommended to avoid disabling the IA key, as this has higher performanceoverhead than disabling any of the other keys.