Magellan Linux

Contents of /trunk/systemd/patches/systemd-242-random-util-eat-up-bad-RDRAND-values-seen-on-amd-cpus.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3368 - (show annotations) (download)
Tue Jul 9 11:20:22 2019 UTC (4 years, 10 months ago) by niro
File size: 2282 byte(s)
-added systemd-242 upstream patches
1 From 1c53d4a070edbec8ad2d384ba0014d0eb6bae077 Mon Sep 17 00:00:00 2001
2 From: Lennart Poettering <lennart@poettering.net>
3 Date: Fri, 10 May 2019 15:16:16 -0400
4 Subject: [PATCH] random-util: eat up bad RDRAND values seen on AMD CPUs
5
6 An ugly, ugly work-around for #11810. And no, we shouldn't have to do
7 this. This is something for AMD, the firmware or the kernel to
8 fix/work-around, not us. But nonetheless, this should do it for now.
9
10 Fixes: #11810
11 ---
12 src/basic/random-util.c | 15 ++++++++++++++-
13 1 file changed, 14 insertions(+), 1 deletion(-)
14
15 diff --git a/src/basic/random-util.c b/src/basic/random-util.c
16 index b8bbf2d418f..0561f0cb227 100644
17 --- a/src/basic/random-util.c
18 +++ b/src/basic/random-util.c
19 @@ -35,6 +35,7 @@ int rdrand(unsigned long *ret) {
20
21 #if defined(__i386__) || defined(__x86_64__)
22 static int have_rdrand = -1;
23 + unsigned long v;
24 uint8_t success;
25
26 if (have_rdrand < 0) {
27 @@ -59,12 +60,24 @@ int rdrand(unsigned long *ret) {
28
29 asm volatile("rdrand %0;"
30 "setc %1"
31 - : "=r" (*ret),
32 + : "=r" (v),
33 "=qm" (success));
34 msan_unpoison(&success, sizeof(success));
35 if (!success)
36 return -EAGAIN;
37
38 + /* Apparently on some AMD CPUs RDRAND will sometimes (after a suspend/resume cycle?) report success
39 + * via the carry flag but nonetheless return the same fixed value -1 in all cases. This appears to be
40 + * a bad bug in the CPU or firmware. Let's deal with that and work-around this by explicitly checking
41 + * for this special value (and also 0, just to be sure) and filtering it out. This is a work-around
42 + * only however and something AMD really should fix properly. The Linux kernel should probably work
43 + * around this issue by turning off RDRAND altogether on those CPUs. See:
44 + * https://github.com/systemd/systemd/issues/11810 */
45 + if (v == 0 || v == ULONG_MAX)
46 + return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
47 + "RDRAND returned suspicious value %lx, assuming bad hardware RNG, not using value.", v);
48 +
49 + *ret = v;
50 return 0;
51 #else
52 return -EOPNOTSUPP;