lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1835548e-8f64-9e3b-59c2-9391ec5b7f13@amd.com>
Date:   Wed, 10 Jan 2018 12:33:22 -0600
From:   Tom Lendacky <thomas.lendacky@....com>
To:     mingo@...nel.org, peterz@...radead.org,
        linux-kernel@...r.kernel.org, ak@...ux.intel.com, hpa@...or.com,
        dave.hansen@...el.com, riel@...hat.com,
        torvalds@...ux-foundation.org, luto@...capital.net,
        gregkh@...ux-foundation.org, tglx@...utronix.de, jikos@...nel.org,
        tim.c.chen@...ux.intel.com, pjt@...gle.com, dwmw@...zon.co.uk,
        keescook@...gle.com, linux-tip-commits@...r.kernel.org
Subject: Re: [tip:x86/pti] x86/spectre: Add boot time option to select Spectre
 v2 mitigation

On 1/10/2018 12:14 PM, tip-bot for David Woodhouse wrote:
> Commit-ID:  fe1678d070e36070c43005c71ce783df57852252
> Gitweb:     https://git.kernel.org/tip/fe1678d070e36070c43005c71ce783df57852252
> Author:     David Woodhouse <dwmw@...zon.co.uk>
> AuthorDate: Tue, 9 Jan 2018 14:43:09 +0000
> Committer:  Thomas Gleixner <tglx@...utronix.de>
> CommitDate: Wed, 10 Jan 2018 19:09:09 +0100
> 
> x86/spectre: Add boot time option to select Spectre v2 mitigation
> 
> Add a spectre_v2= option to select the mitigation used for the indirect
> branch speculation vulnerability.
> 
> Currently, the only option available is retpoline, in its various forms.
> This will be expanded to cover the new IBRS/IBPB microcode features.
> 
> The RETPOLINE_AMD feature relies on a serializing LFENCE for speculation
> control. For AMD hardware, only set RETPOLINE_AMD if LFENCE is a
> serializing instruction, which is indicated by the LFENCE_RDTSC feature.
> 
> [ tglx: Folded back the LFENCE/AMD fixes and reworked it so IBRS
>   	integration becomes simple ]
> 
> Signed-off-by: David Woodhouse <dwmw@...zon.co.uk>
> Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
> Cc: gnomes@...rguk.ukuu.org.uk
> Cc: Rik van Riel <riel@...hat.com>
> Cc: Andi Kleen <ak@...ux.intel.com>
> Cc: Peter Zijlstra <peterz@...radead.org>
> Cc: Linus Torvalds <torvalds@...ux-foundation.org>
> Cc: Jiri Kosina <jikos@...nel.org>
> Cc: Andy Lutomirski <luto@...capital.net>
> Cc: Dave Hansen <dave.hansen@...el.com>
> Cc: Kees Cook <keescook@...gle.com>
> Cc: Tim Chen <tim.c.chen@...ux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@...ux-foundation.org>
> Cc: Paul Turner <pjt@...gle.com>
> Cc: Tom Lendacky <thomas.lendacky@....com>
> Link: https://lkml.kernel.org/r/1515508997-6154-4-git-send-email-dwmw@amazon.co.uk
> 
> 
> ---
>  Documentation/admin-guide/kernel-parameters.txt |  28 +++++
>  arch/x86/include/asm/nospec-branch.h            |  10 ++
>  arch/x86/kernel/cpu/bugs.c                      | 158 +++++++++++++++++++++++-
>  arch/x86/kernel/cpu/common.c                    |   4 -
>  4 files changed, 195 insertions(+), 5 deletions(-)
> 

...

> diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
> index 76ad6cb..4f7a2a0 100644
> --- a/arch/x86/kernel/cpu/bugs.c
> +++ b/arch/x86/kernel/cpu/bugs.c
> @@ -11,6 +11,9 @@
>  #include <linux/init.h>
>  #include <linux/utsname.h>
>  #include <linux/cpu.h>
> +
> +#include <asm/nospec-branch.h>
> +#include <asm/cmdline.h>
>  #include <asm/bugs.h>
>  #include <asm/processor.h>
>  #include <asm/processor-flags.h>
> @@ -21,6 +24,8 @@
>  #include <asm/pgtable.h>
>  #include <asm/set_memory.h>
>  
> +static void __init spectre_v2_select_mitigation(void);
> +
>  void __init check_bugs(void)
>  {
>  	identify_boot_cpu();
> @@ -30,6 +35,9 @@ void __init check_bugs(void)
>  		print_cpu_info(&boot_cpu_data);
>  	}
>  
> +	/* Select the proper spectre mitigation before patching alternatives */
> +	spectre_v2_select_mitigation();
> +
>  #ifdef CONFIG_X86_32
>  	/*
>  	 * Check whether we are able to run this kernel safely on SMP.
> @@ -62,6 +70,153 @@ void __init check_bugs(void)
>  #endif
>  }
>  
> +/* The kernel command line selection */
> +enum spectre_v2_mitigation_cmd {
> +	SPECTRE_V2_CMD_NONE,
> +	SPECTRE_V2_CMD_AUTO,
> +	SPECTRE_V2_CMD_FORCE,
> +	SPECTRE_V2_CMD_RETPOLINE,
> +	SPECTRE_V2_CMD_RETPOLINE_GENERIC,
> +	SPECTRE_V2_CMD_RETPOLINE_AMD,
> +};
> +
> +static const char *spectre_v2_strings[] = {
> +	[SPECTRE_V2_NONE]			= "Vulnerable",
> +	[SPECTRE_V2_RETPOLINE_MINIMAL]		= "Vulnerable: Minimal generic ASM retpoline",
> +	[SPECTRE_V2_RETPOLINE_MINIMAL_AMD]	= "Vulnerable: Minimal AMD ASM retpoline",
> +	[SPECTRE_V2_RETPOLINE_GENERIC]		= "Mitigation: Full generic retpoline",
> +	[SPECTRE_V2_RETPOLINE_AMD]		= "Mitigation: Full AMD retpoline",
> +};
> +
> +#undef pr_fmt
> +#define pr_fmt(fmt)     "Spectre V2 mitigation: " fmt
> +
> +static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
> +
> +static void __init spec2_print_if_insecure(const char *reason)
> +{
> +	if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
> +		pr_info("%s\n", reason);
> +}
> +
> +static void __init spec2_print_if_secure(const char *reason)
> +{
> +	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
> +		pr_info("%s\n", reason);
> +}
> +
> +static inline bool retp_compiler(void)
> +{
> +	return __is_defined(RETPOLINE);
> +}
> +
> +static inline bool match_option(const char *arg, int arglen, const char *opt)
> +{
> +	int len = strlen(opt);
> +
> +	return len == arglen && !strncmp(arg, opt, len);
> +}
> +
> +static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
> +{
> +	char arg[20];
> +	int ret;
> +
> +	ret = cmdline_find_option(boot_command_line, "spectre_v2", arg,
> +				  sizeof(arg));
> +	if (ret > 0)  {
> +		if (match_option(arg, ret, "off")) {
> +			goto disable;
> +		} else if (match_option(arg, ret, "on")) {
> +			spec2_print_if_secure("force enabled on command line.");
> +			return SPECTRE_V2_CMD_FORCE;
> +		} else if (match_option(arg, ret, "retpoline")) {
> +			spec2_print_if_insecure("retpoline selected on command line.");
> +			return SPECTRE_V2_CMD_RETPOLINE;
> +		} else if (match_option(arg, ret, "retpoline,amd")) {
> +			if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {

I missed this in the first review, but this should be != X86_VENDOR_AMD.
Sorry about that.

Thanks,
Tom

> +				pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n");
> +				return SPECTRE_V2_CMD_AUTO;
> +			}
> +			spec2_print_if_insecure("AMD retpoline selected on command line.");
> +			return SPECTRE_V2_CMD_RETPOLINE_AMD;
> +		} else if (match_option(arg, ret, "retpoline,generic")) {
> +			spec2_print_if_insecure("generic retpoline selected on command line.");
> +			return SPECTRE_V2_CMD_RETPOLINE_GENERIC;
> +		} else if (match_option(arg, ret, "auto")) {
> +			return SPECTRE_V2_CMD_AUTO;
> +		}
> +	}
> +
> +	if (!cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
> +		return SPECTRE_V2_CMD_AUTO;
> +disable:
> +	spec2_print_if_insecure("disabled on command line.");
> +	return SPECTRE_V2_CMD_NONE;
> +}
> +
> +static void __init spectre_v2_select_mitigation(void)
> +{
> +	enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
> +	enum spectre_v2_mitigation mode = SPECTRE_V2_NONE;
> +
> +	/*
> +	 * If the CPU is not affected and the command line mode is NONE or AUTO
> +	 * then nothing to do.
> +	 */
> +	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2) &&
> +	    (cmd == SPECTRE_V2_CMD_NONE || cmd == SPECTRE_V2_CMD_AUTO))
> +		return;
> +
> +	switch (cmd) {
> +	case SPECTRE_V2_CMD_NONE:
> +		return;
> +
> +	case SPECTRE_V2_CMD_FORCE:
> +		/* FALLTRHU */
> +	case SPECTRE_V2_CMD_AUTO:
> +		goto retpoline_auto;
> +
> +	case SPECTRE_V2_CMD_RETPOLINE_AMD:
> +		if (IS_ENABLED(CONFIG_RETPOLINE))
> +			goto retpoline_amd;
> +		break;
> +	case SPECTRE_V2_CMD_RETPOLINE_GENERIC:
> +		if (IS_ENABLED(CONFIG_RETPOLINE))
> +			goto retpoline_generic;
> +		break;
> +	case SPECTRE_V2_CMD_RETPOLINE:
> +		if (IS_ENABLED(CONFIG_RETPOLINE))
> +			goto retpoline_auto;
> +		break;
> +	}
> +	pr_err("kernel not compiled with retpoline; no mitigation available!");
> +	return;
> +
> +retpoline_auto:
> +	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
> +	retpoline_amd:
> +		if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
> +			pr_err("LFENCE not serializing. Switching to generic retpoline\n");
> +			goto retpoline_generic;
> +		}
> +		mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD :
> +					 SPECTRE_V2_RETPOLINE_MINIMAL_AMD;
> +		setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
> +		setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
> +	} else {
> +	retpoline_generic:
> +		mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_GENERIC :
> +					 SPECTRE_V2_RETPOLINE_MINIMAL;
> +		setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
> +	}
> +
> +	spectre_v2_enabled = mode;
> +	pr_info("%s\n", spectre_v2_strings[mode]);
> +}
> +
> +#undef pr_fmt
> +
>  #ifdef CONFIG_SYSFS
>  ssize_t cpu_show_meltdown(struct device *dev,
>  			  struct device_attribute *attr, char *buf)
> @@ -86,6 +241,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
>  {
>  	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
>  		return sprintf(buf, "Not affected\n");
> -	return sprintf(buf, "Vulnerable\n");
> +
> +	return sprintf(buf, "%s\n", spectre_v2_strings[spectre_v2_enabled]);
>  }
>  #endif
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 7a671d1..372ba3f 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -905,10 +905,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
>  	setup_force_cpu_bug(X86_BUG_SPECTRE_V1);
>  	setup_force_cpu_bug(X86_BUG_SPECTRE_V2);
>  
> -#ifdef CONFIG_RETPOLINE
> -	setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
> -#endif
> -
>  	fpu__init_system(c);
>  
>  #ifdef CONFIG_X86_32
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ