9dd7462461
by cherry-picking the relevant commits from launchpad/lunar [0]. (relevant commits are based on k.o/stable commits for this) minimally tested by booting my (ryzen) machine with this kernel and skimming through dmesg after boot. [0] git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/lunar Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
173 lines
7.4 KiB
Diff
173 lines
7.4 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Daniel Sneddon <daniel.sneddon@linux.intel.com>
|
|
Date: Wed, 12 Jul 2023 19:43:12 -0700
|
|
Subject: [PATCH] x86/speculation: Add force option to GDS mitigation
|
|
|
|
The Gather Data Sampling (GDS) vulnerability allows malicious software
|
|
to infer stale data previously stored in vector registers. This may
|
|
include sensitive data such as cryptographic keys. GDS is mitigated in
|
|
microcode, and systems with up-to-date microcode are protected by
|
|
default. However, any affected system that is running with older
|
|
microcode will still be vulnerable to GDS attacks.
|
|
|
|
Since the gather instructions used by the attacker are part of the
|
|
AVX2 and AVX512 extensions, disabling these extensions prevents gather
|
|
instructions from being executed, thereby mitigating the system from
|
|
GDS. Disabling AVX2 is sufficient, but we don't have the granularity
|
|
to do this. The XCR0[2] disables AVX, with no option to just disable
|
|
AVX2.
|
|
|
|
Add a kernel parameter gather_data_sampling=force that will enable the
|
|
microcode mitigation if available, otherwise it will disable AVX on
|
|
affected systems.
|
|
|
|
This option will be ignored if cmdline mitigations=off.
|
|
|
|
This is a *big* hammer. It is known to break buggy userspace that
|
|
uses incomplete, buggy AVX enumeration. Unfortunately, such userspace
|
|
does exist in the wild:
|
|
|
|
https://www.mail-archive.com/bug-coreutils@gnu.org/msg33046.html
|
|
|
|
[ dhansen: add some more ominous warnings about disabling AVX ]
|
|
|
|
Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
|
|
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
|
|
Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
|
|
|
|
(cherry picked from commit 553a5c03e90a6087e88f8ff878335ef0621536fb)
|
|
CVE-2022-40982
|
|
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
|
Acked-by: Roxana Nicolescu <roxana.nicolescu@canonical.com>
|
|
Acked-by: Stefan Bader <stefan.bader@canonical.com>
|
|
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
|
|
(cherry picked from commit b73421edcd9b8f1b1db51168e4568667d74422db)
|
|
Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
|
|
---
|
|
.../hw-vuln/gather_data_sampling.rst | 18 +++++++++++++----
|
|
.../admin-guide/kernel-parameters.txt | 8 +++++++-
|
|
arch/x86/kernel/cpu/bugs.c | 20 ++++++++++++++++++-
|
|
3 files changed, 40 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
index 74dab6af7fe1..40b7a6260010 100644
|
|
--- a/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
+++ b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
@@ -60,14 +60,21 @@ bits:
|
|
================================ === ============================
|
|
|
|
GDS can also be mitigated on systems that don't have updated microcode by
|
|
-disabling AVX. This can be done by setting "clearcpuid=avx" on the kernel
|
|
-command-line.
|
|
+disabling AVX. This can be done by setting gather_data_sampling="force" or
|
|
+"clearcpuid=avx" on the kernel command-line.
|
|
+
|
|
+If used, these options will disable AVX use by turning on XSAVE YMM support.
|
|
+However, the processor will still enumerate AVX support. Userspace that
|
|
+does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM
|
|
+support will break.
|
|
|
|
Mitigation control on the kernel command line
|
|
---------------------------------------------
|
|
The mitigation can be disabled by setting "gather_data_sampling=off" or
|
|
-"mitigations=off" on the kernel command line. Not specifying either will
|
|
-default to the mitigation being enabled.
|
|
+"mitigations=off" on the kernel command line. Not specifying either will default
|
|
+to the mitigation being enabled. Specifying "gather_data_sampling=force" will
|
|
+use the microcode mitigation when available or disable AVX on affected systems
|
|
+where the microcode hasn't been updated to include the mitigation.
|
|
|
|
GDS System Information
|
|
------------------------
|
|
@@ -83,6 +90,9 @@ The possible values contained in this file are:
|
|
Vulnerable Processor vulnerable and mitigation disabled.
|
|
Vulnerable: No microcode Processor vulnerable and microcode is missing
|
|
mitigation.
|
|
+ Mitigation: AVX disabled,
|
|
+ no microcode Processor is vulnerable and microcode is missing
|
|
+ mitigation. AVX disabled as mitigation.
|
|
Mitigation: Microcode Processor is vulnerable and mitigation is in
|
|
effect.
|
|
Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in
|
|
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
|
index 380e1e46ffa1..5fef2f65f634 100644
|
|
--- a/Documentation/admin-guide/kernel-parameters.txt
|
|
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
|
@@ -1620,7 +1620,13 @@
|
|
|
|
This issue is mitigated by default in updated microcode.
|
|
The mitigation may have a performance impact but can be
|
|
- disabled.
|
|
+ disabled. On systems without the microcode mitigation
|
|
+ disabling AVX serves as a mitigation.
|
|
+
|
|
+ force: Disable AVX to mitigate systems without
|
|
+ microcode mitigation. No effect if the microcode
|
|
+ mitigation is present. Known to cause crashes in
|
|
+ userspace with buggy AVX enumeration.
|
|
|
|
off: Disable GDS mitigation.
|
|
|
|
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
|
|
index a1c1c8e4995c..0cc3c4f09dd7 100644
|
|
--- a/arch/x86/kernel/cpu/bugs.c
|
|
+++ b/arch/x86/kernel/cpu/bugs.c
|
|
@@ -652,6 +652,7 @@ early_param("l1d_flush", l1d_flush_parse_cmdline);
|
|
enum gds_mitigations {
|
|
GDS_MITIGATION_OFF,
|
|
GDS_MITIGATION_UCODE_NEEDED,
|
|
+ GDS_MITIGATION_FORCE,
|
|
GDS_MITIGATION_FULL,
|
|
GDS_MITIGATION_FULL_LOCKED,
|
|
GDS_MITIGATION_HYPERVISOR,
|
|
@@ -662,6 +663,7 @@ static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL
|
|
static const char * const gds_strings[] = {
|
|
[GDS_MITIGATION_OFF] = "Vulnerable",
|
|
[GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
|
|
+ [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode",
|
|
[GDS_MITIGATION_FULL] = "Mitigation: Microcode",
|
|
[GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)",
|
|
[GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status",
|
|
@@ -687,6 +689,7 @@ void update_gds_msr(void)
|
|
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
mcu_ctrl &= ~GDS_MITG_DIS;
|
|
break;
|
|
+ case GDS_MITIGATION_FORCE:
|
|
case GDS_MITIGATION_UCODE_NEEDED:
|
|
case GDS_MITIGATION_HYPERVISOR:
|
|
return;
|
|
@@ -721,10 +724,23 @@ static void __init gds_select_mitigation(void)
|
|
|
|
/* No microcode */
|
|
if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
|
|
- gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
|
|
+ if (gds_mitigation == GDS_MITIGATION_FORCE) {
|
|
+ /*
|
|
+ * This only needs to be done on the boot CPU so do it
|
|
+ * here rather than in update_gds_msr()
|
|
+ */
|
|
+ setup_clear_cpu_cap(X86_FEATURE_AVX);
|
|
+ pr_warn("Microcode update needed! Disabling AVX as mitigation.\n");
|
|
+ } else {
|
|
+ gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
|
|
+ }
|
|
goto out;
|
|
}
|
|
|
|
+ /* Microcode has mitigation, use it */
|
|
+ if (gds_mitigation == GDS_MITIGATION_FORCE)
|
|
+ gds_mitigation = GDS_MITIGATION_FULL;
|
|
+
|
|
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
if (mcu_ctrl & GDS_MITG_LOCKED) {
|
|
if (gds_mitigation == GDS_MITIGATION_OFF)
|
|
@@ -755,6 +771,8 @@ static int __init gds_parse_cmdline(char *str)
|
|
|
|
if (!strcmp(str, "off"))
|
|
gds_mitigation = GDS_MITIGATION_OFF;
|
|
+ else if (!strcmp(str, "force"))
|
|
+ gds_mitigation = GDS_MITIGATION_FORCE;
|
|
|
|
return 0;
|
|
}
|