xref: /OK3568_Linux_fs/kernel/Documentation/arm64/pointer-authentication.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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