x86/cpuid: Prevent out of bound access in do_clear_cpu_cap()
authorThomas Gleixner <tglx@linutronix.de>
Wed, 18 Oct 2017 17:39:35 +0000 (19:39 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 18 Oct 2017 18:03:34 +0000 (20:03 +0200)
do_clear_cpu_cap() allocates a bitmap to keep track of disabled feature
dependencies. That bitmap is sized NCAPINTS * BITS_PER_INIT. The possible
'features' which can be handed in are larger than this, because after the
capabilities the bug 'feature' bits occupy another 32bit. Not really
obvious...

So clearing any of the misfeature bits, as 32bit does for the F00F bug,
accesses that bitmap out of bounds thereby corrupting the stack.

Size the bitmap proper and add a sanity check to catch accidental out of
bound access.

Fixes: 0b00de857a64 ("x86/cpuid: Add generic table for CPUID dependencies")
Reported-by: kernel test robot <xiaolong.ye@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Link: https://lkml.kernel.org/r/20171018022023.GA12058@yexl-desktop
arch/x86/kernel/cpu/cpuid-deps.c

index e48eb731312042ed55bdacab6ca1d218abaed9a7..c1d49842a411fb0c9f6c5527f64019f9c1bac4e9 100644 (file)
@@ -75,11 +75,17 @@ static inline void clear_feature(struct cpuinfo_x86 *c, unsigned int feature)
                __clear_cpu_cap(c, feature);
 }
 
+/* Take the capabilities and the BUG bits into account */
+#define MAX_FEATURE_BITS ((NCAPINTS + NBUGINTS) * sizeof(u32) * 8)
+
 static void do_clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
 {
-       bool changed;
-       DECLARE_BITMAP(disable, NCAPINTS * sizeof(u32) * 8);
+       DECLARE_BITMAP(disable, MAX_FEATURE_BITS);
        const struct cpuid_dep *d;
+       bool changed;
+
+       if (WARN_ON(feature >= MAX_FEATURE_BITS))
+               return;
 
        clear_feature(c, feature);