Commit | Line | Data |
---|---|---|
b693d0b3 | 1 | ======================================= |
fbedc599 MR |
2 | Pointer authentication in AArch64 Linux |
3 | ======================================= | |
4 | ||
5 | Author: Mark Rutland <mark.rutland@arm.com> | |
b693d0b3 | 6 | |
fbedc599 MR |
7 | Date: 2017-07-19 |
8 | ||
9 | This document briefly describes the provision of pointer authentication | |
10 | functionality in AArch64 Linux. | |
11 | ||
12 | ||
13 | Architecture overview | |
14 | --------------------- | |
15 | ||
16 | The ARMv8.3 Pointer Authentication extension adds primitives that can be | |
17 | used to mitigate certain classes of attack where an attacker can corrupt | |
18 | the contents of some memory (e.g. the stack). | |
19 | ||
20 | The extension uses a Pointer Authentication Code (PAC) to determine | |
21 | whether pointers have been modified unexpectedly. A PAC is derived from | |
22 | a pointer, another value (such as the stack pointer), and a secret key | |
23 | held in system registers. | |
24 | ||
25 | The extension adds instructions to insert a valid PAC into a pointer, | |
26 | and to verify/remove the PAC from a pointer. The PAC occupies a number | |
27 | of high-order bits of the pointer, which varies dependent on the | |
28 | configured virtual address size and whether pointer tagging is in use. | |
29 | ||
30 | A subset of these instructions have been allocated from the HINT | |
31 | encoding space. In the absence of the extension (or when disabled), | |
32 | these instructions behave as NOPs. Applications and libraries using | |
33 | these instructions operate correctly regardless of the presence of the | |
34 | extension. | |
35 | ||
36 | The extension provides five separate keys to generate PACs - two for | |
37 | instruction addresses (APIAKey, APIBKey), two for data addresses | |
38 | (APDAKey, APDBKey), and one for generic authentication (APGAKey). | |
39 | ||
40 | ||
41 | Basic support | |
42 | ------------- | |
43 | ||
44 | When CONFIG_ARM64_PTR_AUTH is selected, and relevant HW support is | |
45 | present, the kernel will assign random key values to each process at | |
46 | exec*() time. The keys are shared by all threads within the process, and | |
47 | are preserved across fork(). | |
48 | ||
49 | Presence of address authentication functionality is advertised via | |
50 | HWCAP_PACA, and generic authentication functionality via HWCAP_PACG. | |
51 | ||
52 | The number of bits that the PAC occupies in a pointer is 55 minus the | |
53 | virtual address size configured by the kernel. For example, with a | |
54 | virtual address size of 48, the PAC is 7 bits wide. | |
55 | ||
56 | Recent versions of GCC can compile code with APIAKey-based return | |
57 | address protection when passed the -msign-return-address option. This | |
58 | uses instructions in the HINT space (unless -march=armv8.3-a or higher | |
59 | is also passed), and such code can run on systems without the pointer | |
60 | authentication extension. | |
61 | ||
62 | In addition to exec(), keys can also be reinitialized to random values | |
63 | using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY, | |
64 | PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEY | |
65 | specifies which keys are to be reinitialized; specifying 0 means "all | |
66 | keys". | |
67 | ||
68 | ||
69 | Debugging | |
70 | --------- | |
71 | ||
72 | When CONFIG_ARM64_PTR_AUTH is selected, and HW support for address | |
73 | authentication is present, the kernel will expose the position of TTBR0 | |
74 | PAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), which | |
75 | userspace can acquire via PTRACE_GETREGSET. | |
76 | ||
77 | The regset is exposed only when HWCAP_PACA is set. Separate masks are | |
78 | exposed for data pointers and instruction pointers, as the set of PAC | |
79 | bits can vary between the two. Note that the masks apply to TTBR0 | |
80 | addresses, and are not valid to apply to TTBR1 addresses (e.g. kernel | |
81 | pointers). | |
82 | ||
d0a060be KM |
83 | Additionally, when CONFIG_CHECKPOINT_RESTORE is also set, the kernel |
84 | will expose the NT_ARM_PACA_KEYS and NT_ARM_PACG_KEYS regsets (struct | |
85 | user_pac_address_keys and struct user_pac_generic_keys). These can be | |
86 | used to get and set the keys for a thread. | |
87 | ||
fbedc599 MR |
88 | |
89 | Virtualization | |
90 | -------------- | |
91 | ||
a22fa321 ADK |
92 | Pointer authentication is enabled in KVM guest when each virtual cpu is |
93 | initialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] and | |
94 | requesting these two separate cpu features to be enabled. The current KVM | |
95 | guest implementation works by enabling both features together, so both | |
96 | these userspace flags are checked before enabling pointer authentication. | |
97 | The separate userspace flag will allow to have no userspace ABI changes | |
98 | if support is added in the future to allow these two features to be | |
99 | enabled independently of one another. | |
100 | ||
101 | As Arm Architecture specifies that Pointer Authentication feature is | |
102 | implemented along with the VHE feature so KVM arm64 ptrauth code relies | |
103 | on VHE mode to be present. | |
104 | ||
105 | Additionally, when these vcpu feature flags are not set then KVM will | |
106 | filter out the Pointer Authentication system key registers from | |
107 | KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID | |
108 | register. Any attempt to use the Pointer Authentication instructions will | |
109 | result in an UNDEFINED exception being injected into the guest. |