Commit ae070226 authored by Josh Poimboeuf's avatar Josh Poimboeuf Committed by Yang Yingliang
Browse files

x86/srso: Fix vulnerability reporting for missing microcode

mainline inclusion
from mainline-v6.7-rc1
commit dc6306ad5b0dda040baf1fde3cfd458e6abfc4da
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9NZ3E

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=dc6306ad5b0dda040baf1fde3cfd458e6abfc4da



--------------------------------

The SRSO default safe-ret mitigation is reported as "mitigated" even if
microcode hasn't been updated.  That's wrong because userspace may still
be vulnerable to SRSO attacks due to IBPB not flushing branch type
predictions.

Report the safe-ret + !microcode case as vulnerable.

Also report the microcode-only case as vulnerable as it leaves the
kernel open to attacks.

Fixes: fb3bd914 ("x86/srso: Add a Speculative RAS Overflow mitigation")
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Acked-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/a8a14f97d1b0e03ec255c81637afdf4cf0ae9c99.1693889988.git.jpoimboe@kernel.org


Conflicts:
	Documentation/admin-guide/hw-vuln/srso.rst
	arch/x86/kernel/cpu/bugs.c
[yyl: adjust context]
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 09c5239e
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -44,12 +44,19 @@ The possible values in this file are:

 - 'Not affected'               The processor is not vulnerable

 - 'Vulnerable'                 The processor is vulnerable and no mitigations have been applied.
 - 'Vulnerable: no microcode'   The processor is vulnerable, no
                                microcode extending IBPB functionality
                                to address the vulnerability has been
                                applied.

 - 'Mitigation: microcode'      Extended IBPB functionality microcode
 - 'Vulnerable: Safe RET, no microcode'
                                The "Safe RET" mitigation (see below) has
                                been applied to protect the kernel, but the
                                IBPB-extending microcode has not been applied.
                                User space tasks may still be vulnerable.

 - 'Vulnerable: Microcode, no safe RET'
                                Extended IBPB functionality microcode
                                patch has been applied. It does not
                                address User->Kernel and Guest->Host
                                transitions protection but it does
@@ -58,9 +65,9 @@ The possible values in this file are:

                                (spec_rstack_overflow=microcode)

 - 'Mitigation: safe RET'       Software-only mitigation. It complements
                                the extended IBPB microcode patch
                                functionality by addressing User->Kernel
 - 'Mitigation: Safe RET'       Combined microcode/software mitigation.
                                It complements the extended IBPB microcode
                                patch functionality by addressing User->Kernel
                                and Guest->Host transitions protection.

                                Selected by default or by
@@ -112,7 +119,7 @@ an indrect branch prediction barrier after having applied the required
microcode patch for one's system. This mitigation comes also at
a performance cost.

Mitigation: safe RET
Mitigation: Safe RET
--------------------

The mitigation works by ensuring all RET instructions speculate to
+22 −14
Original line number Diff line number Diff line
@@ -2251,6 +2251,8 @@ early_param("l1tf", l1tf_cmdline);

enum srso_mitigation {
	SRSO_MITIGATION_NONE,
	SRSO_MITIGATION_UCODE_NEEDED,
	SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED,
	SRSO_MITIGATION_MICROCODE,
	SRSO_MITIGATION_SAFE_RET,
	SRSO_MITIGATION_IBPB,
@@ -2267,8 +2269,10 @@ enum srso_mitigation_cmd {

static const char * const srso_strings[] = {
	[SRSO_MITIGATION_NONE]			= "Vulnerable",
	[SRSO_MITIGATION_MICROCODE]      = "Mitigation: microcode",
	[SRSO_MITIGATION_SAFE_RET]	 = "Mitigation: safe RET",
	[SRSO_MITIGATION_UCODE_NEEDED]		= "Vulnerable: No microcode",
	[SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED]	= "Vulnerable: Safe RET, no microcode",
	[SRSO_MITIGATION_MICROCODE]		= "Vulnerable: Microcode, no safe RET",
	[SRSO_MITIGATION_SAFE_RET]		= "Mitigation: Safe RET",
	[SRSO_MITIGATION_IBPB]			= "Mitigation: IBPB",
	[SRSO_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT only"
};
@@ -2307,10 +2311,7 @@ static void __init srso_select_mitigation(void)
	if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())
		goto pred_cmd;

	if (!has_microcode) {
		pr_warn("IBPB-extending microcode not applied!\n");
		pr_warn(SRSO_NOTICE);
	} else {
	if (has_microcode) {
		/*
		 * Zen1/2 with SMT off aren't vulnerable after the right
		 * IBPB microcode has been applied.
@@ -2327,6 +2328,12 @@ static void __init srso_select_mitigation(void)
			srso_mitigation = SRSO_MITIGATION_IBPB;
			goto pred_cmd;
		}
	} else {
		pr_warn("IBPB-extending microcode not applied!\n");
		pr_warn(SRSO_NOTICE);

		/* may be overwritten by SRSO_CMD_SAFE_RET below */
		srso_mitigation = SRSO_MITIGATION_UCODE_NEEDED;
	}

	switch (srso_cmd) {
@@ -2356,7 +2363,10 @@ static void __init srso_select_mitigation(void)
				setup_force_cpu_cap(X86_FEATURE_SRSO);
				x86_return_thunk = srso_return_thunk;
			}
			if (has_microcode)
				srso_mitigation = SRSO_MITIGATION_SAFE_RET;
			else
				srso_mitigation = SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED;
		} else {
			pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
			goto pred_cmd;
@@ -2391,7 +2401,7 @@ static void __init srso_select_mitigation(void)
		break;
	}

	pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
	pr_info("%s\n", srso_strings[srso_mitigation]);

pred_cmd:
	if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) &&
@@ -2608,9 +2618,7 @@ static ssize_t srso_show_state(char *buf)
	if (boot_cpu_has(X86_FEATURE_SRSO_NO))
		return sysfs_emit(buf, "Mitigation: SMT disabled\n");

	return sysfs_emit(buf, "%s%s\n",
			  srso_strings[srso_mitigation],
			  boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
	return sysfs_emit(buf, "%s\n", srso_strings[srso_mitigation]);
}

static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,