Skip to content

Commit

Permalink
Merge pull request #3373 from foersleo/kernel_div0_fix
Browse files Browse the repository at this point in the history
kernel: Cherry-pick fix for CVE-2023-20588 ("DIV0")
  • Loading branch information
foersleo authored Aug 30, 2023
2 parents 3858477 + e33dee6 commit 9d30b4c
Show file tree
Hide file tree
Showing 12 changed files with 742 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
From d573bee81157742dfb6710646d365bcd37a0f92c Mon Sep 17 00:00:00 2001
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Sat, 8 Jul 2023 10:21:35 +0200
Subject: [PATCH] x86/bugs: Increase the x86 bugs vector size to two u32s

Upstream commit: 0e52740ffd10c6c316837c6c128f460f1aaba1ea

There was never a doubt in my mind that they would not fit into a single
u32 eventually.

Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
(cherry picked from commit 073a28a9b50662991e7d6956c2cf2fc5d54f28cd)
Signed-off-by: Leonard Foerster <[email protected]>
---
arch/x86/include/asm/cpufeatures.h | 2 +-
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 0b0b9453b19f..9b06e142bad1 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -14,7 +14,7 @@
* Defines x86 CPU feature bits
*/
#define NCAPINTS 19 /* N 32-bit words worth of info */
-#define NBUGINTS 1 /* N 32-bit bug flags */
+#define NBUGINTS 2 /* N 32-bit bug flags */

/*
* Note: If the comment begins with a quoted string, that string is used
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 54ba20492ad1..51a8fdb487c7 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -14,7 +14,7 @@
* Defines x86 CPU feature bits
*/
#define NCAPINTS 19 /* N 32-bit words worth of info */
-#define NBUGINTS 1 /* N 32-bit bug flags */
+#define NBUGINTS 2 /* N 32-bit bug flags */

/*
* Note: If the comment begins with a quoted string, that string is used
--
2.40.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
From 188ef20eb7f347966659092d75051f0cd4b572bf Mon Sep 17 00:00:00 2001
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Sat, 5 Aug 2023 00:06:43 +0200
Subject: [PATCH] x86/CPU/AMD: Do not leak quotient data after a division by 0

commit 77245f1c3c6495521f6a3af082696ee2f8ce3921 upstream.

Under certain circumstances, an integer division by 0 which faults, can
leave stale quotient data from a previous division operation on Zen1
microarchitectures.

Do a dummy division 0/1 before returning from the #DE exception handler
in order to avoid any leaks of potentially sensitive data.

Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Cc: <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
(cherry picked from commit b6fc2fbf89089ecfb8eb9a89a7fc91d444f4fec7)
Signed-off-by: Leonard Foerster <[email protected]>
---
arch/x86/include/asm/cpufeatures.h | 2 ++
arch/x86/include/asm/processor.h | 2 ++
arch/x86/kernel/cpu/amd.c | 19 +++++++++++++++++++
arch/x86/kernel/traps.c | 2 ++
4 files changed, 25 insertions(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 9b06e142bad1..630196281a48 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -435,4 +435,6 @@
#define X86_BUG_RAS_POISONING X86_BUG(29) /* CPU is affected by RAS poisoning */
#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */

+/* BUG word 2 */
+#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 12714134f5eb..f20dc0c73cae 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -810,9 +810,11 @@ DECLARE_PER_CPU(u64, msr_misc_features_shadow);
#ifdef CONFIG_CPU_SUP_AMD
extern u16 amd_get_nb_id(int cpu);
extern u32 amd_get_nodes_per_socket(void);
+extern void amd_clear_divider(void);
#else
static inline u16 amd_get_nb_id(int cpu) { return 0; }
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
+static inline void amd_clear_divider(void) { }
#endif

static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 3d99a823ffac..842357ee7724 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -76,6 +76,10 @@ static const int amd_zenbleed[] =
AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf),
AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf));

+static const int amd_div0[] =
+ AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf),
+ AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf));
+
static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
{
int osvw_id = *erratum++;
@@ -1168,6 +1172,11 @@ static void init_amd(struct cpuinfo_x86 *c)
check_null_seg_clears_base(c);

zenbleed_check(c);
+
+ if (cpu_has_amd_erratum(c, amd_div0)) {
+ pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n");
+ setup_force_cpu_bug(X86_BUG_DIV0);
+ }
}

#ifdef CONFIG_X86_32
@@ -1293,3 +1302,13 @@ void amd_check_microcode(void)
{
on_each_cpu(zenbleed_check_cpu, NULL, 1);
}
+
+/*
+ * Issue a DIV 0/1 insn to clear any division data from previous DIV
+ * operations.
+ */
+void noinstr amd_clear_divider(void)
+{
+ asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
+ :: "a" (0), "d" (0), "r" (1));
+}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 3780c728345c..d8142b5738ac 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -198,6 +198,8 @@ DEFINE_IDTENTRY(exc_divide_error)
{
do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE,
FPE_INTDIV, error_get_trap_addr(regs));
+
+ amd_clear_divider();
}

DEFINE_IDTENTRY(exc_overflow)
--
2.40.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
From ea19dbd49d7dcdfa1a807ce1ea48164f10129113 Mon Sep 17 00:00:00 2001
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Fri, 11 Aug 2023 23:38:24 +0200
Subject: [PATCH] x86/CPU/AMD: Fix the DIV(0) initial fix attempt

commit f58d6fbcb7c848b7f2469be339bc571f2e9d245b upstream.

Initially, it was thought that doing an innocuous division in the #DE
handler would take care to prevent any leaking of old data from the
divider but by the time the fault is raised, the speculation has already
advanced too far and such data could already have been used by younger
operations.

Therefore, do the innocuous division on every exit to userspace so that
userspace doesn't see any potentially old data from integer divisions in
kernel space.

Do the same before VMRUN too, to protect host data from leaking into the
guest too.

Fixes: 77245f1c3c64 ("x86/CPU/AMD: Do not leak quotient data after a division by 0")
Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Cc: <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
(cherry picked from commit 69712baf249570a1419e75dc1a103a44e375b2cd)
Signed-off-by: Leonard Foerster <[email protected]>
---
arch/x86/include/asm/entry-common.h | 1 +
arch/x86/kernel/cpu/amd.c | 1 +
arch/x86/kernel/traps.c | 2 --
arch/x86/kvm/svm/svm.c | 1 +
4 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h
index 4a382fb6a9ef..5443851d3aa6 100644
--- a/arch/x86/include/asm/entry-common.h
+++ b/arch/x86/include/asm/entry-common.h
@@ -78,6 +78,7 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
static __always_inline void arch_exit_to_user_mode(void)
{
mds_user_clear_cpu_buffers();
+ amd_clear_divider();
}
#define arch_exit_to_user_mode arch_exit_to_user_mode

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 842357ee7724..64e97f243441 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1312,3 +1312,4 @@ void noinstr amd_clear_divider(void)
asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
:: "a" (0), "d" (0), "r" (1));
}
+EXPORT_SYMBOL_GPL(amd_clear_divider);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index d8142b5738ac..3780c728345c 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -198,8 +198,6 @@ DEFINE_IDTENTRY(exc_divide_error)
{
do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE,
FPE_INTDIV, error_get_trap_addr(regs));
-
- amd_clear_divider();
}

DEFINE_IDTENTRY(exc_overflow)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 5ddc75ade8f0..d0a1c0420c92 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3381,6 +3381,7 @@ static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)

static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
{
+ amd_clear_divider();
}

static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
--
2.40.1

6 changes: 6 additions & 0 deletions packages/kernel-5.10/kernel-5.10.spec
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ Patch2001: 2001-kbuild-add-support-for-zstd-compressed-modules.patch
Patch5001: 5001-x86-cpu-amd-Move-the-errata-checking-functionality-u.patch
Patch5002: 5002-x86-cpu-amd-Add-a-Zenbleed-fix.patch

# Cherry-picked fixes for CVE-2023-20588 ("DIV0"). Can be dropped when moving
# upstream to 5.10.192 or later.
Patch5011: 5011-x86-bugs-Increase-the-x86-bugs-vector-size-to-two-u3.patch
Patch5012: 5012-x86-CPU-AMD-Do-not-leak-quotient-data-after-a-divisi.patch
Patch5013: 5013-x86-CPU-AMD-Fix-the-DIV-0-initial-fix-attempt.patch

BuildRequires: bc
BuildRequires: elfutils-devel
BuildRequires: hostname
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
From 40f837f02c448b37fb8967e5c50878c8a4e9459a Mon Sep 17 00:00:00 2001
From: "Borislav Petkov (AMD)" <[email protected]>
Date: Sat, 8 Jul 2023 10:21:35 +0200
Subject: [PATCH] x86/bugs: Increase the x86 bugs vector size to two u32s

Upstream commit: 0e52740ffd10c6c316837c6c128f460f1aaba1ea

There was never a doubt in my mind that they would not fit into a single
u32 eventually.

Signed-off-by: Borislav Petkov (AMD) <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
(cherry picked from commit 236dd7133394bfe30275191e3aefcc6b3b09962b)
Signed-off-by: Leonard Foerster <[email protected]>
---
arch/x86/include/asm/cpufeatures.h | 2 +-
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index ad6984f941f7..3800d0ec048d 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -14,7 +14,7 @@
* Defines x86 CPU feature bits
*/
#define NCAPINTS 20 /* N 32-bit words worth of info */
-#define NBUGINTS 1 /* N 32-bit bug flags */
+#define NBUGINTS 2 /* N 32-bit bug flags */

/*
* Note: If the comment begins with a quoted string, that string is used
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 3781a7f489ef..da6d66e1fbb1 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -14,7 +14,7 @@
* Defines x86 CPU feature bits
*/
#define NCAPINTS 20 /* N 32-bit words worth of info */
-#define NBUGINTS 1 /* N 32-bit bug flags */
+#define NBUGINTS 2 /* N 32-bit bug flags */

/*
* Note: If the comment begins with a quoted string, that string is used
--
2.40.1

Loading

0 comments on commit 9d30b4c

Please sign in to comment.