1*4882a593Smuzhiyun======================================= 2*4882a593SmuzhiyunPointer authentication in AArch64 Linux 3*4882a593Smuzhiyun======================================= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunAuthor: Mark Rutland <mark.rutland@arm.com> 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunDate: 2017-07-19 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunThis document briefly describes the provision of pointer authentication 10*4882a593Smuzhiyunfunctionality in AArch64 Linux. 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunArchitecture overview 14*4882a593Smuzhiyun--------------------- 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunThe ARMv8.3 Pointer Authentication extension adds primitives that can be 17*4882a593Smuzhiyunused to mitigate certain classes of attack where an attacker can corrupt 18*4882a593Smuzhiyunthe contents of some memory (e.g. the stack). 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunThe extension uses a Pointer Authentication Code (PAC) to determine 21*4882a593Smuzhiyunwhether pointers have been modified unexpectedly. A PAC is derived from 22*4882a593Smuzhiyuna pointer, another value (such as the stack pointer), and a secret key 23*4882a593Smuzhiyunheld in system registers. 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunThe extension adds instructions to insert a valid PAC into a pointer, 26*4882a593Smuzhiyunand to verify/remove the PAC from a pointer. The PAC occupies a number 27*4882a593Smuzhiyunof high-order bits of the pointer, which varies dependent on the 28*4882a593Smuzhiyunconfigured virtual address size and whether pointer tagging is in use. 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunA subset of these instructions have been allocated from the HINT 31*4882a593Smuzhiyunencoding space. In the absence of the extension (or when disabled), 32*4882a593Smuzhiyunthese instructions behave as NOPs. Applications and libraries using 33*4882a593Smuzhiyunthese instructions operate correctly regardless of the presence of the 34*4882a593Smuzhiyunextension. 35*4882a593Smuzhiyun 36*4882a593SmuzhiyunThe extension provides five separate keys to generate PACs - two for 37*4882a593Smuzhiyuninstruction addresses (APIAKey, APIBKey), two for data addresses 38*4882a593Smuzhiyun(APDAKey, APDBKey), and one for generic authentication (APGAKey). 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunBasic support 42*4882a593Smuzhiyun------------- 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunWhen CONFIG_ARM64_PTR_AUTH is selected, and relevant HW support is 45*4882a593Smuzhiyunpresent, the kernel will assign random key values to each process at 46*4882a593Smuzhiyunexec*() time. The keys are shared by all threads within the process, and 47*4882a593Smuzhiyunare preserved across fork(). 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunPresence of address authentication functionality is advertised via 50*4882a593SmuzhiyunHWCAP_PACA, and generic authentication functionality via HWCAP_PACG. 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunThe number of bits that the PAC occupies in a pointer is 55 minus the 53*4882a593Smuzhiyunvirtual address size configured by the kernel. For example, with a 54*4882a593Smuzhiyunvirtual address size of 48, the PAC is 7 bits wide. 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunRecent versions of GCC can compile code with APIAKey-based return 57*4882a593Smuzhiyunaddress protection when passed the -msign-return-address option. This 58*4882a593Smuzhiyunuses instructions in the HINT space (unless -march=armv8.3-a or higher 59*4882a593Smuzhiyunis also passed), and such code can run on systems without the pointer 60*4882a593Smuzhiyunauthentication extension. 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunIn addition to exec(), keys can also be reinitialized to random values 63*4882a593Smuzhiyunusing the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, 64*4882a593SmuzhiyunPR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEY 65*4882a593Smuzhiyunspecifies which keys are to be reinitialized; specifying 0 means "all 66*4882a593Smuzhiyunkeys". 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunDebugging 70*4882a593Smuzhiyun--------- 71*4882a593Smuzhiyun 72*4882a593SmuzhiyunWhen CONFIG_ARM64_PTR_AUTH is selected, and HW support for address 73*4882a593Smuzhiyunauthentication is present, the kernel will expose the position of TTBR0 74*4882a593SmuzhiyunPAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), which 75*4882a593Smuzhiyunuserspace can acquire via PTRACE_GETREGSET. 76*4882a593Smuzhiyun 77*4882a593SmuzhiyunThe regset is exposed only when HWCAP_PACA is set. Separate masks are 78*4882a593Smuzhiyunexposed for data pointers and instruction pointers, as the set of PAC 79*4882a593Smuzhiyunbits can vary between the two. Note that the masks apply to TTBR0 80*4882a593Smuzhiyunaddresses, and are not valid to apply to TTBR1 addresses (e.g. kernel 81*4882a593Smuzhiyunpointers). 82*4882a593Smuzhiyun 83*4882a593SmuzhiyunAdditionally, when CONFIG_CHECKPOINT_RESTORE is also set, the kernel 84*4882a593Smuzhiyunwill expose the NT_ARM_PACA_KEYS and NT_ARM_PACG_KEYS regsets (struct 85*4882a593Smuzhiyunuser_pac_address_keys and struct user_pac_generic_keys). These can be 86*4882a593Smuzhiyunused to get and set the keys for a thread. 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunVirtualization 90*4882a593Smuzhiyun-------------- 91*4882a593Smuzhiyun 92*4882a593SmuzhiyunPointer authentication is enabled in KVM guest when each virtual cpu is 93*4882a593Smuzhiyuninitialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] and 94*4882a593Smuzhiyunrequesting these two separate cpu features to be enabled. The current KVM 95*4882a593Smuzhiyunguest implementation works by enabling both features together, so both 96*4882a593Smuzhiyunthese userspace flags are checked before enabling pointer authentication. 97*4882a593SmuzhiyunThe separate userspace flag will allow to have no userspace ABI changes 98*4882a593Smuzhiyunif support is added in the future to allow these two features to be 99*4882a593Smuzhiyunenabled independently of one another. 100*4882a593Smuzhiyun 101*4882a593SmuzhiyunAs Arm Architecture specifies that Pointer Authentication feature is 102*4882a593Smuzhiyunimplemented along with the VHE feature so KVM arm64 ptrauth code relies 103*4882a593Smuzhiyunon VHE mode to be present. 104*4882a593Smuzhiyun 105*4882a593SmuzhiyunAdditionally, when these vcpu feature flags are not set then KVM will 106*4882a593Smuzhiyunfilter out the Pointer Authentication system key registers from 107*4882a593SmuzhiyunKVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID 108*4882a593Smuzhiyunregister. Any attempt to use the Pointer Authentication instructions will 109*4882a593Smuzhiyunresult in an UNDEFINED exception being injected into the guest. 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunEnabling and disabling keys 113*4882a593Smuzhiyun--------------------------- 114*4882a593Smuzhiyun 115*4882a593SmuzhiyunThe prctl PR_PAC_SET_ENABLED_KEYS allows the user program to control which 116*4882a593SmuzhiyunPAC keys are enabled in a particular task. It takes two arguments, the 117*4882a593Smuzhiyunfirst being a bitmask of PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY 118*4882a593Smuzhiyunand PR_PAC_APDBKEY specifying which keys shall be affected by this prctl, 119*4882a593Smuzhiyunand the second being a bitmask of the same bits specifying whether the key 120*4882a593Smuzhiyunshould be enabled or disabled. For example:: 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun prctl(PR_PAC_SET_ENABLED_KEYS, 123*4882a593Smuzhiyun PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY, 124*4882a593Smuzhiyun PR_PAC_APIBKEY, 0, 0); 125*4882a593Smuzhiyun 126*4882a593Smuzhiyundisables all keys except the IB key. 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunThe main reason why this is useful is to enable a userspace ABI that uses PAC 129*4882a593Smuzhiyuninstructions to sign and authenticate function pointers and other pointers 130*4882a593Smuzhiyunexposed outside of the function, while still allowing binaries conforming to 131*4882a593Smuzhiyunthe ABI to interoperate with legacy binaries that do not sign or authenticate 132*4882a593Smuzhiyunpointers. 133*4882a593Smuzhiyun 134*4882a593SmuzhiyunThe idea is that a dynamic loader or early startup code would issue this 135*4882a593Smuzhiyunprctl very early after establishing that a process may load legacy binaries, 136*4882a593Smuzhiyunbut before executing any PAC instructions. 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunFor compatibility with previous kernel versions, processes start up with IA, 139*4882a593SmuzhiyunIB, DA and DB enabled, and are reset to this state on exec(). Processes created 140*4882a593Smuzhiyunvia fork() and clone() inherit the key enabled state from the calling process. 141*4882a593Smuzhiyun 142*4882a593SmuzhiyunIt is recommended to avoid disabling the IA key, as this has higher performance 143*4882a593Smuzhiyunoverhead than disabling any of the other keys. 144