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: <03a3a4d135b17115db9ad91413e21af73e244500.1587555769.git.john.haxby@oracle.com>
Date:   Wed, 22 Apr 2020 13:03:19 +0100
From:   John Haxby <john.haxby@...cle.com>
To:     Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        "H. Peter Anvin" <hpa@...or.com>, Andi Kleen <ak@...ux.intel.com>,
        Jonathan Corbet <corbet@....net>
Cc:     x86@...nel.org, linux-doc@...r.kernel.org,
        linux-kernel@...r.kernel.org, John Haxby <john.haxby@...cle.com>,
        stable@...r.kernel.org
Subject: [PATCH 1/1] x86/fpu: Allow clearcpuid= to clear several bits

Prior to 0c2a3913d6f5, clearcpuid= could be specified several times on
the command line to clear several bits. The old multiple option is a
little anachronistic so change clearcpuid to accept a comma-separated
list of numbers. Up to about eight bits can be cleared.

Fixes: 0c2a3913d6f5 ("x86/fpu: Parse clearcpuid= as early XSAVE argument")
Signed-off-by: John Haxby <john.haxby@...cle.com>
Cc: stable@...r.kernel.org
---
 .../admin-guide/kernel-parameters.txt         | 24 ++++++++++---------
 arch/x86/kernel/fpu/init.c                    | 18 ++++++++------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f2a93c8679e8..f380781be9e0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -577,18 +577,20 @@
 			loops can be debugged more effectively on production
 			systems.
 
-	clearcpuid=BITNUM [X86]
-			Disable CPUID feature X for the kernel. See
+	clearcpuid=BITNUM[,BITNUM,...] [X86]
+			Disable CPUID features for the kernel. See
 			arch/x86/include/asm/cpufeatures.h for the valid bit
-			numbers. Note the Linux specific bits are not necessarily
-			stable over kernel options, but the vendor specific
-			ones should be.
-			Also note that user programs calling CPUID directly
-			or using the feature without checking anything
-			will still see it. This just prevents it from
-			being used by the kernel or shown in /proc/cpuinfo.
-			Also note the kernel might malfunction if you disable
-			some critical bits.
+			numbers. Up to about eight bits can be cleared. Note the
+			Linux specific bits are not necessarily stable over
+			kernel options, but the vendor specific ones should be.
+			Also note that user programs calling CPUID directly or
+			using the feature without checking anything will still
+			see it. This just prevents it from being used by the
+			kernel or shown in /proc/cpuinfo.  Also note the kernel
+			might malfunction if you disable some critical bits.
+			Consider using a virtual machine emulating an older CPU
+			type for clearing many bits or for making the cleared
+			bits visible to user programs.
 
 	cma=nn[MG]@[start[MG][-end[MG]]]
 			[ARM,X86,KNL]
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 6ce7e0a23268..8d826505c22e 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -243,8 +243,6 @@ static void __init fpu__init_system_ctx_switch(void)
 static void __init fpu__init_parse_early_param(void)
 {
 	char arg[32];
-	char *argptr = arg;
-	int bit;
 
 #ifdef CONFIG_X86_32
 	if (cmdline_find_option_bool(boot_command_line, "no387"))
@@ -268,11 +266,17 @@ static void __init fpu__init_parse_early_param(void)
 		setup_clear_cpu_cap(X86_FEATURE_XSAVES);
 
 	if (cmdline_find_option(boot_command_line, "clearcpuid", arg,
-				sizeof(arg)) &&
-	    get_option(&argptr, &bit) &&
-	    bit >= 0 &&
-	    bit < NCAPINTS * 32)
-		setup_clear_cpu_cap(bit);
+				sizeof(arg))) {
+		/* cpuid bit numbers are mostly three digits */
+		enum  { nints = sizeof(arg)/(3+1) + 1 };
+		int i, bits[nints];
+
+		get_options(arg, nints, bits);
+		for (i = 1; i <= bits[0]; i++) {
+			if (bits[i] >= 0 && bits[i] < NCAPINTS * 32)
+				setup_clear_cpu_cap(bits[i]);
+		}
+	}
 }
 
 /*
-- 
2.25.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ