Skip to content

Commit c644b7e

Browse files
committed
Merge: x86/rfds: Mitigate Register File Data Sampling (RFDS)
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/3961 JIRA: https://issues.redhat.com/browse/RHEL-31226 MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/3961 RFDS (Register File Data Sampling - CVE-2023-28746) is a CPU vulnerability that may allow userspace to infer kernel stale data previously used in floating point registers, vector registers and integer registers. RFDS only affects certain Intel Atom processors. Intel released a microcode update that uses VERW instruction to clear the affected CPU buffers. Unlike MDS, none of the affected cores support SMT. This MR backports the upstream kernel mitigation to RHEL. New microcode is also needed to complete the mitigation. Signed-off-by: Waiman Long <longman@redhat.com> Approved-by: Steve Best <sbest@redhat.com> Approved-by: Chris von Recklinghausen <crecklin@redhat.com> Approved-by: Rafael Aquini <aquini@redhat.com> Approved-by: Josh Poimboeuf <jpoimboe@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents f5527be + 7e2c8bc commit c644b7e

File tree

24 files changed

+391
-55
lines changed

24 files changed

+391
-55
lines changed

Documentation/ABI/testing/sysfs-devices-system-cpu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ What: /sys/devices/system/cpu/vulnerabilities
524524
/sys/devices/system/cpu/vulnerabilities/mds
525525
/sys/devices/system/cpu/vulnerabilities/meltdown
526526
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
527+
/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
527528
/sys/devices/system/cpu/vulnerabilities/retbleed
528529
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
529530
/sys/devices/system/cpu/vulnerabilities/spectre_v1

Documentation/admin-guide/hw-vuln/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ are configurable at compile, boot or run time.
2121
cross-thread-rsb
2222
srso
2323
gather_data_sampling
24+
reg-file-data-sampling
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
==================================
2+
Register File Data Sampling (RFDS)
3+
==================================
4+
5+
Register File Data Sampling (RFDS) is a microarchitectural vulnerability that
6+
only affects Intel Atom parts(also branded as E-cores). RFDS may allow
7+
a malicious actor to infer data values previously used in floating point
8+
registers, vector registers, or integer registers. RFDS does not provide the
9+
ability to choose which data is inferred. CVE-2023-28746 is assigned to RFDS.
10+
11+
Affected Processors
12+
===================
13+
Below is the list of affected Intel processors [#f1]_:
14+
15+
=================== ============
16+
Common name Family_Model
17+
=================== ============
18+
ATOM_GOLDMONT 06_5CH
19+
ATOM_GOLDMONT_D 06_5FH
20+
ATOM_GOLDMONT_PLUS 06_7AH
21+
ATOM_TREMONT_D 06_86H
22+
ATOM_TREMONT 06_96H
23+
ALDERLAKE 06_97H
24+
ALDERLAKE_L 06_9AH
25+
ATOM_TREMONT_L 06_9CH
26+
RAPTORLAKE 06_B7H
27+
RAPTORLAKE_P 06_BAH
28+
ATOM_GRACEMONT 06_BEH
29+
RAPTORLAKE_S 06_BFH
30+
=================== ============
31+
32+
As an exception to this table, Intel Xeon E family parts ALDERLAKE(06_97H) and
33+
RAPTORLAKE(06_B7H) codenamed Catlow are not affected. They are reported as
34+
vulnerable in Linux because they share the same family/model with an affected
35+
part. Unlike their affected counterparts, they do not enumerate RFDS_CLEAR or
36+
CPUID.HYBRID. This information could be used to distinguish between the
37+
affected and unaffected parts, but it is deemed not worth adding complexity as
38+
the reporting is fixed automatically when these parts enumerate RFDS_NO.
39+
40+
Mitigation
41+
==========
42+
Intel released a microcode update that enables software to clear sensitive
43+
information using the VERW instruction. Like MDS, RFDS deploys the same
44+
mitigation strategy to force the CPU to clear the affected buffers before an
45+
attacker can extract the secrets. This is achieved by using the otherwise
46+
unused and obsolete VERW instruction in combination with a microcode update.
47+
The microcode clears the affected CPU buffers when the VERW instruction is
48+
executed.
49+
50+
Mitigation points
51+
-----------------
52+
VERW is executed by the kernel before returning to user space, and by KVM
53+
before VMentry. None of the affected cores support SMT, so VERW is not required
54+
at C-state transitions.
55+
56+
New bits in IA32_ARCH_CAPABILITIES
57+
----------------------------------
58+
Newer processors and microcode update on existing affected processors added new
59+
bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
60+
vulnerability and mitigation capability:
61+
62+
- Bit 27 - RFDS_NO - When set, processor is not affected by RFDS.
63+
- Bit 28 - RFDS_CLEAR - When set, processor is affected by RFDS, and has the
64+
microcode that clears the affected buffers on VERW execution.
65+
66+
Mitigation control on the kernel command line
67+
---------------------------------------------
68+
The kernel command line allows to control RFDS mitigation at boot time with the
69+
parameter "reg_file_data_sampling=". The valid arguments are:
70+
71+
========== =================================================================
72+
on If the CPU is vulnerable, enable mitigation; CPU buffer clearing
73+
on exit to userspace and before entering a VM.
74+
off Disables mitigation.
75+
========== =================================================================
76+
77+
Mitigation default is selected by CONFIG_MITIGATION_RFDS.
78+
79+
Mitigation status information
80+
-----------------------------
81+
The Linux kernel provides a sysfs interface to enumerate the current
82+
vulnerability status of the system: whether the system is vulnerable, and
83+
which mitigations are active. The relevant sysfs file is:
84+
85+
/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
86+
87+
The possible values in this file are:
88+
89+
.. list-table::
90+
91+
* - 'Not affected'
92+
- The processor is not vulnerable
93+
* - 'Vulnerable'
94+
- The processor is vulnerable, but no mitigation enabled
95+
* - 'Vulnerable: No microcode'
96+
- The processor is vulnerable but microcode is not updated.
97+
* - 'Mitigation: Clear Register File'
98+
- The processor is vulnerable and the CPU buffer clearing mitigation is
99+
enabled.
100+
101+
References
102+
----------
103+
.. [#f1] Affected Processors
104+
https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,26 @@
11111111
The filter can be disabled or changed to another
11121112
driver later using sysfs.
11131113

1114+
reg_file_data_sampling=
1115+
[X86] Controls mitigation for Register File Data
1116+
Sampling (RFDS) vulnerability. RFDS is a CPU
1117+
vulnerability which may allow userspace to infer
1118+
kernel data values previously stored in floating point
1119+
registers, vector registers, or integer registers.
1120+
RFDS only affects Intel Atom processors.
1121+
1122+
on: Turns ON the mitigation.
1123+
off: Turns OFF the mitigation.
1124+
1125+
This parameter overrides the compile time default set
1126+
by CONFIG_MITIGATION_RFDS. Mitigation cannot be
1127+
disabled when other VERW based mitigations (like MDS)
1128+
are enabled. In order to disable RFDS mitigation all
1129+
VERW based mitigations need to be disabled.
1130+
1131+
For details see:
1132+
Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
1133+
11141134
driver_async_probe= [KNL]
11151135
List of driver names to be probed asynchronously. *
11161136
matches with all driver names. If * is specified, the
@@ -3274,6 +3294,7 @@
32743294
nospectre_bhb [ARM64]
32753295
nospectre_v1 [X86,PPC]
32763296
nospectre_v2 [X86,PPC,S390,ARM64]
3297+
reg_file_data_sampling=off [X86]
32773298
retbleed=off [X86]
32783299
spec_store_bypass_disable=off [X86,PPC]
32793300
spectre_v2_user=off [X86]

Documentation/x86/mds.rst

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ The kernel provides a function to invoke the buffer clearing:
9595

9696
mds_clear_cpu_buffers()
9797

98+
Also macro CLEAR_CPU_BUFFERS can be used in ASM late in exit-to-user path.
99+
Other than CFLAGS.ZF, this macro doesn't clobber any registers.
100+
98101
The mitigation is invoked on kernel/userspace, hypervisor/guest and C-state
99102
(idle) transitions.
100103

@@ -138,17 +141,30 @@ Mitigation points
138141

139142
When transitioning from kernel to user space the CPU buffers are flushed
140143
on affected CPUs when the mitigation is not disabled on the kernel
141-
command line. The migitation is enabled through the static key
142-
mds_user_clear.
143-
144-
The mitigation is invoked in prepare_exit_to_usermode() which covers
145-
all but one of the kernel to user space transitions. The exception
146-
is when we return from a Non Maskable Interrupt (NMI), which is
147-
handled directly in do_nmi().
148-
149-
(The reason that NMI is special is that prepare_exit_to_usermode() can
150-
enable IRQs. In NMI context, NMIs are blocked, and we don't want to
151-
enable IRQs with NMIs blocked.)
144+
command line. The mitigation is enabled through the feature flag
145+
X86_FEATURE_CLEAR_CPU_BUF.
146+
147+
The mitigation is invoked just before transitioning to userspace after
148+
user registers are restored. This is done to minimize the window in
149+
which kernel data could be accessed after VERW e.g. via an NMI after
150+
VERW.
151+
152+
**Corner case not handled**
153+
Interrupts returning to kernel don't clear CPUs buffers since the
154+
exit-to-user path is expected to do that anyways. But, there could be
155+
a case when an NMI is generated in kernel after the exit-to-user path
156+
has cleared the buffers. This case is not handled and NMI returning to
157+
kernel don't clear CPU buffers because:
158+
159+
1. It is rare to get an NMI after VERW, but before returning to userspace.
160+
2. For an unprivileged user, there is no known way to make that NMI
161+
less rare or target it.
162+
3. It would take a large number of these precisely-timed NMIs to mount
163+
an actual attack. There's presumably not enough bandwidth.
164+
4. The NMI in question occurs after a VERW, i.e. when user state is
165+
restored and most interesting data is already scrubbed. Whats left
166+
is only the data that NMI touches, and that may or may not be of
167+
any interest.
152168

153169

154170
2. C-State transition

arch/x86/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,6 +2655,17 @@ config GDS_FORCE_MITIGATION
26552655

26562656
If in doubt, say N.
26572657

2658+
config MITIGATION_RFDS
2659+
bool "RFDS Mitigation"
2660+
depends on CPU_SUP_INTEL
2661+
default y
2662+
help
2663+
Enable mitigation for Register File Data Sampling (RFDS) by default.
2664+
RFDS is a hardware vulnerability which affects Intel Atom CPUs. It
2665+
allows unprivileged speculative access to stale data previously
2666+
stored in floating point, vector and integer registers.
2667+
See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
2668+
26582669
endif
26592670

26602671
config ARCH_HAS_ADD_PAGES

arch/x86/entry/entry.S

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include <linux/linkage.h>
77
#include <asm/export.h>
88
#include <asm/msr-index.h>
9+
#include <asm/unwind_hints.h>
10+
#include <asm/segment.h>
11+
#include <asm/cache.h>
912

1013
.pushsection .noinstr.text, "ax"
1114

@@ -20,3 +23,23 @@ SYM_FUNC_END(entry_ibpb)
2023
EXPORT_SYMBOL_GPL(entry_ibpb);
2124

2225
.popsection
26+
27+
/*
28+
* Define the VERW operand that is disguised as entry code so that
29+
* it can be referenced with KPTI enabled. This ensure VERW can be
30+
* used late in exit-to-user path after page tables are switched.
31+
*/
32+
.pushsection .entry.text, "ax"
33+
34+
.align L1_CACHE_BYTES, 0xcc
35+
SYM_CODE_START_NOALIGN(mds_verw_sel)
36+
UNWIND_HINT_EMPTY
37+
ANNOTATE_NOENDBR
38+
.word __KERNEL_DS
39+
.align L1_CACHE_BYTES, 0xcc
40+
SYM_CODE_END(mds_verw_sel);
41+
/* For KVM */
42+
EXPORT_SYMBOL_GPL(mds_verw_sel);
43+
44+
.popsection
45+

arch/x86/entry/entry_32.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,7 @@ SYM_FUNC_START(entry_SYSENTER_32)
899899
BUG_IF_WRONG_CR3 no_user_check=1
900900
popfl
901901
popl %eax
902+
CLEAR_CPU_BUFFERS
902903

903904
/*
904905
* Return back to the vDSO, which will pop ecx and edx.
@@ -968,6 +969,7 @@ restore_all_switch_stack:
968969

969970
/* Restore user state */
970971
RESTORE_REGS pop=4 # skip orig_eax/error_code
972+
CLEAR_CPU_BUFFERS
971973
.Lirq_return:
972974
/*
973975
* ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
@@ -1160,6 +1162,7 @@ SYM_CODE_START(asm_exc_nmi)
11601162

11611163
/* Not on SYSENTER stack. */
11621164
call exc_nmi
1165+
CLEAR_CPU_BUFFERS
11631166
jmp .Lnmi_return
11641167

11651168
.Lnmi_from_sysenter_stack:

arch/x86/entry/entry_64.S

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ syscall_return_via_sysret:
161161
SYM_INNER_LABEL(entry_SYSRETQ_unsafe_stack, SYM_L_GLOBAL)
162162
ANNOTATE_NOENDBR
163163
swapgs
164+
CLEAR_CPU_BUFFERS
164165
sysretq
165166
SYM_INNER_LABEL(entry_SYSRETQ_end, SYM_L_GLOBAL)
166167
ANNOTATE_NOENDBR
@@ -576,6 +577,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
576577

577578
.Lswapgs_and_iret:
578579
swapgs
580+
CLEAR_CPU_BUFFERS
579581
/* Assert that the IRET frame indicates user mode. */
580582
testb $3, 8(%rsp)
581583
jnz .Lnative_iret
@@ -726,6 +728,8 @@ native_irq_return_ldt:
726728
*/
727729
popq %rax /* Restore user RAX */
728730

731+
CLEAR_CPU_BUFFERS
732+
729733
/*
730734
* RSP now points to an ordinary IRET frame, except that the page
731735
* is read-only and RSP[31:16] are preloaded with the userspace
@@ -1452,6 +1456,12 @@ nmi_restore:
14521456
std
14531457
movq $0, 5*8(%rsp) /* clear "NMI executing" */
14541458

1459+
/*
1460+
* Skip CLEAR_CPU_BUFFERS here, since it only helps in rare cases like
1461+
* NMI in kernel after user state is restored. For an unprivileged user
1462+
* these conditions are hard to meet.
1463+
*/
1464+
14551465
/*
14561466
* iretq reads the "iret" frame and exits the NMI stack in a
14571467
* single instruction. We are returning to kernel mode, so this
@@ -1469,6 +1479,7 @@ SYM_CODE_START(entry_SYSCALL32_ignore)
14691479
UNWIND_HINT_EMPTY
14701480
ENDBR
14711481
mov $-ENOSYS, %eax
1482+
CLEAR_CPU_BUFFERS
14721483
sysretl
14731484
SYM_CODE_END(entry_SYSCALL32_ignore)
14741485

arch/x86/entry/entry_64_compat.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_stack, SYM_L_GLOBAL)
270270
xorl %r9d, %r9d
271271
xorl %r10d, %r10d
272272
swapgs
273+
CLEAR_CPU_BUFFERS
273274
sysretl
274275
SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL)
275276
ANNOTATE_NOENDBR

0 commit comments

Comments
 (0)