]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
x86/rdrand: Sanity-check RDRAND output
authorBorislav Petkov <bp@suse.de>
Sun, 25 Aug 2019 20:50:18 +0000 (22:50 +0200)
committerBorislav Petkov <bp@suse.de>
Tue, 1 Oct 2019 17:55:32 +0000 (19:55 +0200)
It turned out recently that on certain AMD F15h and F16h machines, due
to the BIOS dropping the ball after resume, yet again, RDRAND would not
function anymore:

  c49a0a80137c ("x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h")

Add a silly test to the CPU bringup path, to sanity-check the random
data RDRAND returns and scream as loudly as possible if that returned
random data doesn't change.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Pu Wen <puwen@hygon.cn>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/CAHk-=wjWPDauemCmLTKbdMYFB0UveMszZpcrwoUkJRRWKrqaTw@mail.gmail.com
arch/x86/kernel/cpu/rdrand.c

index 5c900f9527ffb9e1068fc6e85171b4b34bdb91ce..c4be62058dd96053bc0f3a2bc4588135f7010a6f 100644 (file)
@@ -29,7 +29,8 @@ __setup("nordrand", x86_rdrand_setup);
 #ifdef CONFIG_ARCH_RANDOM
 void x86_init_rdrand(struct cpuinfo_x86 *c)
 {
-       unsigned long tmp;
+       unsigned int changed = 0;
+       unsigned long tmp, prev;
        int i;
 
        if (!cpu_has(c, X86_FEATURE_RDRAND))
@@ -42,5 +43,24 @@ void x86_init_rdrand(struct cpuinfo_x86 *c)
                        return;
                }
        }
+
+       /*
+        * Stupid sanity-check whether RDRAND does *actually* generate
+        * some at least random-looking data.
+        */
+       prev = tmp;
+       for (i = 0; i < SANITY_CHECK_LOOPS; i++) {
+               if (rdrand_long(&tmp)) {
+                       if (prev != tmp)
+                               changed++;
+
+                       prev = tmp;
+               }
+       }
+
+       if (WARN_ON_ONCE(!changed))
+               pr_emerg(
+"RDRAND gives funky smelling output, might consider not using it by booting with \"nordrand\"");
+
 }
 #endif