← Documents Documentation/admin-guide/hw-vuln/srso.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Hardware Vulnerabilities

Speculative Return Stack Overflow (SRSO)

AMD Zen SRSO의 BTB·RAP poisoning, Safe RET·IBPB 완화와 perf 검증 절차를 설명합니다.

Source pathDocumentation/admin-guide/hw-vuln/srso.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

취약점과 CPU

srso.rst:1-32

non-architectural CALL과 RAP poisoning 및 영향 Zen family를 설명합니다.

상태와 option

srso.rst:33-154

microcode 요구 사항, sysfs 상태 9개와 완화 선택을 정리합니다.

Safe RET 구현

srso.rst:155-174

Zen 세대별 untraining 및 safe-return thunk를 설명합니다.

perf·selftest 검증

srso.rst:175-242

PMC event, 기대 counter 값과 x86 selftest 명령을 보존합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 Speculative Return Stack Overflow (SRSO)
4 ========================================
5
6 This is a mitigation for the speculative return stack overflow (SRSO)
7 vulnerability found on AMD processors. The mechanism is by now the well
8 known scenario of poisoning CPU functional units - the Branch Target
9 Buffer (BTB) and Return Address Predictor (RAP) in this case - and then
10 tricking the elevated privilege domain (the kernel) into leaking
11 sensitive data.
12
13 AMD CPUs predict RET instructions using a Return Address Predictor (aka
14 Return Address Stack/Return Stack Buffer). In some cases, a non-architectural
15 CALL instruction (i.e., an instruction predicted to be a CALL but is
16 not actually a CALL) can create an entry in the RAP which may be used
17 to predict the target of a subsequent RET instruction.
18
19 The specific circumstances that lead to this varies by microarchitecture
20 but the concern is that an attacker can mis-train the CPU BTB to predict
21 non-architectural CALL instructions in kernel space and use this to
22 control the speculative target of a subsequent kernel RET, potentially
23 leading to information disclosure via a speculative side-channel.
24
25 The issue is tracked under CVE-2023-20569.
26
27 Affected processors
28 -------------------
29
30 AMD Zen, generations 1-4. That is, all families 0x17 and 0x19. Older
31 processors have not been investigated.
32
33 System information and options
34 ------------------------------
35
36 First of all, it is required that the latest microcode be loaded for
37 mitigations to be effective.
38
39 The sysfs file showing SRSO mitigation status is:
40
41 /sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow
42
43 The possible values in this file are:
44
45 * 'Not affected':
46
47 The processor is not vulnerable
48
49 * 'Vulnerable':
50
51 The processor is vulnerable and no mitigations have been applied.
52
53 * 'Vulnerable: No microcode':
54
55 The processor is vulnerable, no microcode extending IBPB
56 functionality to address the vulnerability has been applied.
57
58 * 'Vulnerable: Safe RET, no microcode':
59
60 The "Safe RET" mitigation (see below) has been applied to protect the
61 kernel, but the IBPB-extending microcode has not been applied. User
62 space tasks may still be vulnerable.
63
64 * 'Vulnerable: Microcode, no safe RET':
65
66 Extended IBPB functionality microcode patch has been applied. It does
67 not address User->Kernel and Guest->Host transitions protection but it
68 does address User->User and VM->VM attack vectors.
69
70 Note that User->User mitigation is controlled by how the IBPB aspect in
71 the Spectre v2 mitigation is selected:
72
73 * conditional IBPB:
74
75 where each process can select whether it needs an IBPB issued
76 around it PR_SPEC_DISABLE/_ENABLE etc, see :doc:`spectre`
77
78 * strict:
79
80 i.e., always on - by supplying spectre_v2_user=on on the kernel
81 command line
82
83 (spec_rstack_overflow=microcode)
84
85 * 'Mitigation: Safe RET':
86
87 Combined microcode/software mitigation. It complements the
88 extended IBPB microcode patch functionality by addressing
89 User->Kernel and Guest->Host transitions protection.
90
91 Selected by default or by spec_rstack_overflow=safe-ret
92
93 * 'Mitigation: IBPB':
94
95 Similar protection as "safe RET" above but employs an IBPB barrier on
96 privilege domain crossings (User->Kernel, Guest->Host).
97
98 (spec_rstack_overflow=ibpb)
99
100 * 'Mitigation: IBPB on VMEXIT':
101
102 Mitigation addressing the cloud provider scenario - the Guest->Host
103 transitions only.
104
105 (spec_rstack_overflow=ibpb-vmexit)
106
107 * 'Mitigation: Reduced Speculation':
108
109 This mitigation gets automatically enabled when the above one "IBPB on
110 VMEXIT" has been selected and the CPU supports the BpSpecReduce bit.
111
112 It gets automatically enabled on machines which have the
113 SRSO_USER_KERNEL_NO=1 CPUID bit. In that case, the code logic is to switch
114 to the above =ibpb-vmexit mitigation because the user/kernel boundary is
115 not affected anymore and thus "safe RET" is not needed.
116
117 After enabling the IBPB on VMEXIT mitigation option, the BpSpecReduce bit
118 is detected (functionality present on all such machines) and that
119 practically overrides IBPB on VMEXIT as it has a lot less performance
120 impact and takes care of the guest->host attack vector too.
121
122 In order to exploit vulnerability, an attacker needs to:
123
124 - gain local access on the machine
125
126 - break kASLR
127
128 - find gadgets in the running kernel in order to use them in the exploit
129
130 - potentially create and pin an additional workload on the sibling
131 thread, depending on the microarchitecture (not necessary on fam 0x19)
132
133 - run the exploit
134
135 Considering the performance implications of each mitigation type, the
136 default one is 'Mitigation: safe RET' which should take care of most
137 attack vectors, including the local User->Kernel one.
138
139 As always, the user is advised to keep her/his system up-to-date by
140 applying software updates regularly.
141
142 The default setting will be reevaluated when needed and especially when
143 new attack vectors appear.
144
145 As one can surmise, 'Mitigation: safe RET' does come at the cost of some
146 performance depending on the workload. If one trusts her/his userspace
147 and does not want to suffer the performance impact, one can always
148 disable the mitigation with spec_rstack_overflow=off.
149
150 Similarly, 'Mitigation: IBPB' is another full mitigation type employing
151 an indirect branch prediction barrier after having applied the required
152 microcode patch for one's system. This mitigation comes also at
153 a performance cost.
154
155 Mitigation: Safe RET
156 --------------------
157
158 The mitigation works by ensuring all RET instructions speculate to
159 a controlled location, similar to how speculation is controlled in the
160 retpoline sequence. To accomplish this, the __x86_return_thunk forces
161 the CPU to mispredict every function return using a 'safe return'
162 sequence.
163
164 To ensure the safety of this mitigation, the kernel must ensure that the
165 safe return sequence is itself free from attacker interference. In Zen3
166 and Zen4, this is accomplished by creating a BTB alias between the
167 untraining function srso_alias_untrain_ret() and the safe return
168 function srso_alias_safe_ret() which results in evicting a potentially
169 poisoned BTB entry and using that safe one for all function returns.
170
171 In older Zen1 and Zen2, this is accomplished using a reinterpretation
172 technique similar to Retbleed one: srso_untrain_ret() and
173 srso_safe_ret().
174
175 Checking the safe RET mitigation actually works
176 -----------------------------------------------
177
178 In case one wants to validate whether the SRSO safe RET mitigation works
179 on a kernel, one could use two performance counters
180
181 * PMC_0xc8 - Count of RET/RET lw retired
182 * PMC_0xc9 - Count of RET/RET lw retired mispredicted
183
184 and compare the number of RETs retired properly vs those retired
185 mispredicted, in kernel mode. Another way of specifying those events
186 is::
187
188 # perf list ex_ret_near_ret
189
190 List of pre-defined events (to be used in -e or -M):
191
192 core:
193 ex_ret_near_ret
194 [Retired Near Returns]
195 ex_ret_near_ret_mispred
196 [Retired Near Returns Mispredicted]
197
198 Either the command using the event mnemonics::
199
200 # perf stat -e ex_ret_near_ret:k -e ex_ret_near_ret_mispred:k sleep 10s
201
202 or using the raw PMC numbers::
203
204 # perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
205
206 should give the same amount. I.e., every RET retired should be
207 mispredicted::
208
209 [root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
210
211 Performance counter stats for 'sleep 10s':
212
213 137,167 cpu/event=0xc8,umask=0/k
214 137,173 cpu/event=0xc9,umask=0/k
215
216 10.004110303 seconds time elapsed
217
218 0.000000000 seconds user
219 0.004462000 seconds sys
220
221 vs the case when the mitigation is disabled (spec_rstack_overflow=off)
222 or not functioning properly, showing usually a lot smaller number of
223 mispredicted retired RETs vs the overall count of retired RETs during
224 a workload::
225
226 [root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s
227
228 Performance counter stats for 'sleep 10s':
229
230 201,627 cpu/event=0xc8,umask=0/k
231 4,074 cpu/event=0xc9,umask=0/k
232
233 10.003267252 seconds time elapsed
234
235 0.002729000 seconds user
236 0.000000000 seconds sys
237
238 Also, there is a selftest which performs the above, go to
239 tools/testing/selftests/x86/ and do::
240
241 make srso
242 ./srso
243

3. 한국어 전문 번역

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

SRSO 개요

1-26

이 문서는 AMD 프로세서에서 발견된 Speculative Return Stack Overflow(SRSO) 취약점의 완화를 설명합니다. 공격자는 Branch Target Buffer(BTB)와 Return Address Predictor(RAP) 같은 CPU functional unit을 오염시킨 뒤 높은 privilege domain인 kernel이 민감한 data를 누출하도록 유도합니다.

AMD CPU는 Return Address Predictor, 즉 Return Address Stack 또는 Return Stack Buffer로 `RET`를 예측합니다. 실제 `CALL`은 아니지만 `CALL`로 예측된 non-architectural CALL instruction이 RAP entry를 만들고 이후 `RET` target 예측에 사용될 수 있습니다.

구체적 조건은 microarchitecture마다 다르지만, 공격자가 CPU BTB를 잘못 train해 kernel space의 non-architectural CALL을 예측시키고 이후 kernel `RET`의 speculative target을 제어하면 speculative side channel로 정보가 노출될 수 있습니다.

이 문제는 `CVE-2023-20569`로 추적됩니다.

영향받는 프로세서

27-32

AMD Zen 1~4, 즉 family `0x17`과 `0x19` 전체가 영향을 받습니다. 이전 프로세서는 조사되지 않았습니다.

system 정보와 완화 option

33-154

완화가 효과를 내려면 먼저 최신 microcode를 load해야 합니다.

/sys/devices/system/cpu/vulnerabilities/spec_rstack_overflow
sysfs 상태의미
Not affected프로세서가 취약하지 않습니다.
Vulnerable프로세서가 취약하고 적용된 완화가 없습니다.
Vulnerable: No microcodeIBPB 기능을 확장하는 완화 microcode가 없습니다.
Vulnerable: Safe RET, no microcodeSafe RET가 kernel을 보호하지만 extended-IBPB microcode가 없어 userspace task는 취약할 수 있습니다.
Vulnerable: Microcode, no safe RETextended IBPB microcode가 User-to-User와 VM-to-VM을 보호하지만 User-to-Kernel과 Guest-to-Host 전환은 보호하지 않습니다. `spec_rstack_overflow=microcode`에 해당합니다.
Mitigation: Safe RETmicrocode와 software를 결합해 User-to-Kernel 및 Guest-to-Host까지 보호합니다. 기본값 또는 `spec_rstack_overflow=safe-ret`로 선택합니다.
Mitigation: IBPBprivilege-domain crossing에서 IBPB barrier를 사용해 Safe RET와 비슷한 보호를 제공합니다. `spec_rstack_overflow=ibpb`입니다.
Mitigation: IBPB on VMEXITcloud-provider 환경의 Guest-to-Host 전환만 보호합니다. `spec_rstack_overflow=ibpb-vmexit`입니다.
Mitigation: Reduced SpeculationIBPB-on-VMEXIT 선택 시 CPU가 `BpSpecReduce`를 지원하면 자동 활성화됩니다. `SRSO_USER_KERNEL_NO=1` CPU에서는 user/kernel boundary가 영향받지 않아 safe RET 대신 이 경로를 선택하며, 성능 비용이 훨씬 작으면서 guest-to-host도 보호합니다.

`Vulnerable: Microcode, no safe RET`에서 User-to-User 보호는 Spectre v2의 IBPB 선택에 달립니다. conditional IBPB에서는 각 process가 `PR_SPEC_DISABLE/_ENABLE` 등으로 자신 주변의 IBPB 필요 여부를 선택합니다. strict mode는 kernel command line의 `spectre_v2_user=on`으로 항상 켭니다.

취약점을 악용하려면 공격자가 다음을 수행해야 합니다.

  • machine에 local access를 얻습니다.
  • kASLR을 깨뜨립니다.
  • exploit에 사용할 running-kernel gadget을 찾습니다.
  • microarchitecture에 따라 sibling thread에 추가 workload를 만들어 pin합니다. family 0x19에는 필요하지 않습니다.
  • exploit을 실행합니다.

성능 영향을 고려한 기본값은 `Mitigation: Safe RET`이며 local User-to-Kernel을 포함한 대부분 attack vector를 다룹니다. system을 정기적으로 update해야 하며 새 attack vector가 등장하면 기본 설정을 재평가합니다.

Safe RET는 workload에 따라 성능 비용이 있습니다. userspace를 신뢰하고 비용을 피하려면 `spec_rstack_overflow=off`로 끌 수 있습니다. 필요한 microcode 뒤에 IBPB를 사용하는 `Mitigation: IBPB`도 완전한 완화지만 역시 성능 비용이 있습니다.

Safe RET 완화

155-174

Safe RET는 retpoline과 비슷하게 모든 `RET`가 통제된 위치로 speculate하도록 합니다. `__x86_return_thunk`가 safe-return sequence로 모든 function return의 misprediction을 강제합니다.

safe-return sequence 자체가 공격자 간섭을 받지 않게 해야 합니다. Zen3·Zen4에서는 untraining function `srso_alias_untrain_ret()`와 safe-return function `srso_alias_safe_ret()` 사이에 BTB alias를 만들어 오염 가능 BTB entry를 evict하고 모든 function return에 안전한 entry를 사용합니다.

Zen1·Zen2에서는 Retbleed와 비슷한 reinterpretation 기법의 `srso_untrain_ret()`와 `srso_safe_ret()`를 사용합니다.

Safe RET 동작 검증

175-239

kernel의 SRSO Safe RET가 동작하는지 검증하려면 `PMC_0xc8`(retired RET/RET lw 수)과 `PMC_0xc9`(mispredicted retired RET/RET lw 수)를 kernel mode에서 비교합니다.

# perf list ex_ret_near_ret

List of pre-defined events (to be used in -e or -M):

core:
  ex_ret_near_ret
       [Retired Near Returns]
  ex_ret_near_ret_mispred
       [Retired Near Returns Mispredicted]

event mnemonic을 사용한 명령은 다음과 같습니다.

# perf stat -e ex_ret_near_ret:k -e ex_ret_near_ret_mispred:k sleep 10s

raw PMC number를 사용하면 다음과 같습니다.

# perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s

완화가 정상이라면 모든 retired RET가 mispredict되어 두 값이 거의 같아야 합니다.

[root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s

 Performance counter stats for 'sleep 10s':

           137,167      cpu/event=0xc8,umask=0/k
           137,173      cpu/event=0xc9,umask=0/k

      10.004110303 seconds time elapsed

       0.000000000 seconds user
       0.004462000 seconds sys

`spec_rstack_overflow=off`로 완화를 껐거나 제대로 동작하지 않으면 workload 동안 전체 retired RET보다 mispredicted retired RET가 훨씬 적습니다.

[root@brent: ~/kernel/linux/tools/perf> ./perf stat -e cpu/event=0xc8,umask=0/k -e cpu/event=0xc9,umask=0/k sleep 10s

 Performance counter stats for 'sleep 10s':

          201,627      cpu/event=0xc8,umask=0/k
            4,074      cpu/event=0xc9,umask=0/k

     10.003267252 seconds time elapsed

      0.002729000 seconds user
      0.000000000 seconds sys

SRSO selftest

240-242

같은 검사를 수행하는 selftest는 `tools/testing/selftests/x86/`에서 실행합니다.

make srso
./srso