← Documents Documentation/arch/arm64/pointer-authentication.rst GitHub 원문 ↗

Linux 6.18.37 · Architecture

Pointer Authentication in AArch64 Linux

PAC 생성과 key 종류, process key 수명, debugging regset, KVM 노출 및 task별 key 활성화 ABI를 설명합니다.

Source pathDocumentation/arch/arm64/pointer-authentication.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

pointer-authentication.rst:1-142

Pointer Authentication은 pointer와 modifier, secret key에서 PAC를 계산해 pointer 변조를 탐지합니다. Linux는 process별 무작위 key, hwcap, ptrace regset, KVM feature flag, prctl을 하나의 ABI로 묶어 보호 기능과 legacy binary 상호 운용을 함께 제공합니다.

PAC 수명 주기
Pointer + modifierSecret keyPAC 계산상위 bit에 삽입사용 전 인증/제거

Pointer에 code를 넣고 사용할 때 검증한 뒤 원래 pointer를 복원합니다.

Linux interface
영역Interface역할
탐지`HWCAP_PACA`, `HWCAP_PACG`Address/generic 기능 광고
Debug`NT_ARM_PAC_*`Mask와 key regset
KVM`KVM_ARM_VCPU_PTRAUTH_*`Guest feature 요청
Task policy`PR_PAC_SET_ENABLED_KEYS`Key enable 상태 선택

기능 탐지, debugging, virtualization, policy 제어 경로입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =======================================
2 Pointer authentication in AArch64 Linux
3 =======================================
4
5 Author: Mark Rutland <mark.rutland@arm.com>
6
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 When ARM64_PTR_AUTH_KERNEL is selected, the kernel will be compiled
57 with HINT space pointer authentication instructions protecting
58 function returns. Kernels built with this option will work on hardware
59 with or without pointer authentication support.
60
61 In addition to exec(), keys can also be reinitialized to random values
62 using the PR_PAC_RESET_KEYS prctl. A bitmask of PR_PAC_APIAKEY,
63 PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY and PR_PAC_APGAKEY
64 specifies which keys are to be reinitialized; specifying 0 means "all
65 keys".
66
67
68 Debugging
69 ---------
70
71 When CONFIG_ARM64_PTR_AUTH is selected, and HW support for address
72 authentication is present, the kernel will expose the position of TTBR0
73 PAC bits in the NT_ARM_PAC_MASK regset (struct user_pac_mask), which
74 userspace can acquire via PTRACE_GETREGSET.
75
76 The regset is exposed only when HWCAP_PACA is set. Separate masks are
77 exposed for data pointers and instruction pointers, as the set of PAC
78 bits can vary between the two. Note that the masks apply to TTBR0
79 addresses, and are not valid to apply to TTBR1 addresses (e.g. kernel
80 pointers).
81
82 Additionally, when CONFIG_CHECKPOINT_RESTORE is also set, the kernel
83 will expose the NT_ARM_PACA_KEYS and NT_ARM_PACG_KEYS regsets (struct
84 user_pac_address_keys and struct user_pac_generic_keys). These can be
85 used to get and set the keys for a thread.
86
87
88 Virtualization
89 --------------
90
91 Pointer authentication is enabled in KVM guest when each virtual cpu is
92 initialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] and
93 requesting these two separate cpu features to be enabled. The current KVM
94 guest implementation works by enabling both features together, so both
95 these userspace flags are checked before enabling pointer authentication.
96 The separate userspace flag will allow to have no userspace ABI changes
97 if support is added in the future to allow these two features to be
98 enabled independently of one another.
99
100 As Arm Architecture specifies that Pointer Authentication feature is
101 implemented along with the VHE feature so KVM arm64 ptrauth code relies
102 on VHE mode to be present.
103
104 Additionally, when these vcpu feature flags are not set then KVM will
105 filter out the Pointer Authentication system key registers from
106 KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID
107 register. Any attempt to use the Pointer Authentication instructions will
108 result in an UNDEFINED exception being injected into the guest.
109
110
111 Enabling and disabling keys
112 ---------------------------
113
114 The prctl PR_PAC_SET_ENABLED_KEYS allows the user program to control which
115 PAC keys are enabled in a particular task. It takes two arguments, the
116 first being a bitmask of PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY
117 and PR_PAC_APDBKEY specifying which keys shall be affected by this prctl,
118 and the second being a bitmask of the same bits specifying whether the key
119 should be enabled or disabled. For example::
120
121 prctl(PR_PAC_SET_ENABLED_KEYS,
122 PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY,
123 PR_PAC_APIBKEY, 0, 0);
124
125 disables all keys except the IB key.
126
127 The main reason why this is useful is to enable a userspace ABI that uses PAC
128 instructions to sign and authenticate function pointers and other pointers
129 exposed outside of the function, while still allowing binaries conforming to
130 the ABI to interoperate with legacy binaries that do not sign or authenticate
131 pointers.
132
133 The idea is that a dynamic loader or early startup code would issue this
134 prctl very early after establishing that a process may load legacy binaries,
135 but before executing any PAC instructions.
136
137 For compatibility with previous kernel versions, processes start up with IA,
138 IB, DA and DB enabled, and are reset to this state on exec(). Processes created
139 via fork() and clone() inherit the key enabled state from the calling process.
140
141 It is recommended to avoid disabling the IA key, as this has higher performance
142 overhead than disabling any of the other keys.
143

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

아키텍처 개요

1-40

저자: Mark Rutland, 2017-07-19. 이 문서는 AArch64 Linux의 pointer authentication 제공 방식을 간략히 설명합니다. ARMv8.3 Pointer Authentication extension은 공격자가 stack 같은 memory 내용을 변조할 수 있을 때 발생하는 일부 공격을 완화하는 primitive를 추가합니다.

Pointer Authentication Code(PAC)는 pointer가 예기치 않게 바뀌었는지 판정합니다. PAC는 pointer, stack pointer 같은 modifier 값, system register에 보관한 secret key로부터 계산됩니다. Extension은 올바른 PAC를 pointer에 넣고, PAC를 검증해 제거하는 명령을 추가합니다.

PAC는 pointer의 상위 bit 일부를 사용하며, 폭은 설정된 virtual address size와 pointer tagging 사용 여부에 따라 달라집니다. 일부 명령은 `HINT` encoding 공간에 배치되어 기능이 없거나 꺼져 있으면 `NOP`처럼 동작합니다. 따라서 이 명령을 쓰는 application과 library는 extension 존재 여부와 무관하게 실행할 수 있습니다.

Key대상
`APIAKey`Instruction address A
`APIBKey`Instruction address B
`APDAKey`Data address A
`APDBKey`Data address B
`APGAKey`Generic authentication

기본 지원

41-67

`CONFIG_ARM64_PTR_AUTH`가 선택되고 관련 hardware가 있으면 커널은 `exec*()` 때 process마다 무작위 key를 할당합니다. Key는 process의 모든 thread가 공유하고 `fork()` 뒤에도 유지됩니다.

Address authentication은 `HWCAP_PACA`, generic authentication은 `HWCAP_PACG`로 광고합니다. Pointer에서 PAC가 차지하는 bit 수는 `55 - kernel VA size`입니다. 예를 들어 VA size가 48이면 PAC 폭은 7비트입니다.

`ARM64_PTR_AUTH_KERNEL`을 선택하면 function return을 보호하는 HINT-space pointer authentication 명령으로 커널을 compile합니다. 이 kernel은 pointer authentication 지원 여부와 무관하게 동작합니다.

`exec()` 외에도 `PR_PAC_RESET_KEYS` prctl로 key를 새 무작위 값으로 초기화할 수 있습니다.

Reset flag대상
`PR_PAC_APIAKEY``APIAKey`
`PR_PAC_APIBKEY``APIBKey`
`PR_PAC_APDAKEY``APDAKey`
`PR_PAC_APDBKEY``APDBKey`
`PR_PAC_APGAKEY``APGAKey`; bitmask가 0이면 모든 key

Debugging interface

68-87

`CONFIG_ARM64_PTR_AUTH`가 선택되고 address authentication hardware가 있으면 커널은 `NT_ARM_PAC_MASK` regset(`struct user_pac_mask`)에 TTBR0 PAC bit 위치를 공개합니다. 사용자 공간은 `PTRACE_GETREGSET`으로 읽을 수 있습니다.

이 regset은 `HWCAP_PACA`가 설정된 경우에만 나타납니다. Data pointer와 instruction pointer의 PAC bit 집합이 다를 수 있으므로 mask도 따로 제공합니다. Mask는 TTBR0 주소에만 적용되며 kernel pointer 같은 TTBR1 주소에는 유효하지 않습니다.

`CONFIG_CHECKPOINT_RESTORE`도 설정되면 `NT_ARM_PACA_KEYS`와 `NT_ARM_PACG_KEYS` regset(`struct user_pac_address_keys`, `struct user_pac_generic_keys`)을 공개하여 thread key를 읽고 쓸 수 있게 합니다.

KVM virtualization

88-110

KVM guest의 각 vCPU를 초기화할 때 `KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC]` flag로 두 CPU feature를 모두 요청하면 pointer authentication을 켭니다. 현재 구현은 두 기능을 함께 enable하므로 두 사용자 공간 flag를 모두 검사합니다. 별도 flag를 유지하는 이유는 나중에 독립 enable을 지원하더라도 userspace ABI를 바꾸지 않기 위해서입니다.

Arm Architecture는 Pointer Authentication이 VHE와 함께 구현된다고 규정하므로 KVM arm64 ptrauth code는 VHE mode에 의존합니다.

vCPU feature flag가 없으면 KVM은 `KVM_GET/SET_REG_*` ioctl에서 Pointer Authentication system key register를 제거하고 cpufeature ID register에서도 기능을 mask합니다. Guest가 Pointer Authentication 명령을 실행하면 `UNDEFINED` exception을 주입합니다.

Key 활성화와 비활성화

111-126

`PR_PAC_SET_ENABLED_KEYS` prctl은 task에서 어떤 PAC key를 enable할지 제어합니다. 첫 argument는 `PR_PAC_APIAKEY`, `PR_PAC_APIBKEY`, `PR_PAC_APDAKEY`, `PR_PAC_APDBKEY` 중 영향을 받을 key의 bitmask이고, 두 번째 argument는 같은 bit 중 실제로 enable할 key의 bitmask입니다.

prctl(PR_PAC_SET_ENABLED_KEYS,
      PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY,
      PR_PAC_APIBKEY, 0, 0);

이 예는 IB key만 남기고 나머지 key를 모두 disable합니다.

ABI 호환성과 초기 상태

127-142

이 제어는 PAC 명령으로 function pointer와 function 밖에 노출되는 다른 pointer를 sign하고 authenticate하는 userspace ABI를 쓰면서도, pointer를 sign하지 않는 legacy binary와 상호 운용할 때 유용합니다.

Dynamic loader 또는 early startup code는 process가 legacy binary를 load할 수 있음을 확인한 직후, 어떤 PAC 명령도 실행하기 전에 이 prctl을 호출해야 합니다.

이전 kernel과의 호환성을 위해 process는 IA, IB, DA, DB가 enable된 상태로 시작하며 `exec()` 때 이 상태로 reset됩니다. `fork()`와 `clone()`으로 만든 process는 caller의 key-enabled state를 상속합니다.

IA key를 disable하면 다른 key를 disable할 때보다 성능 overhead가 크므로 피하는 것이 권장됩니다.