Commit efbcf510 authored by Michael Biebl's avatar Michael Biebl

random-util: Eat up bad RDRAND values seen on AMD CPUs

Some AMD CPUs return bogus data via RDRAND after a suspend/resume cycle
while still reporting success via the carry flag.
Filter out invalid data like -1 (and also 0, just to be sure).

Closes: #921267
parent ae11ca4f
From: Michael Biebl <biebl@debian.org>
Date: Tue, 14 May 2019 13:12:35 +0200
Subject: random-util: eat up bad RDRAND values seen on AMD CPUs
An ugly, ugly work-around for #11810. And no, we shouldn't have to do
this. This is something for AMD, the firmware or the kernel to
fix/work-around, not us. But nonetheless, this should do it for now.
Fixes: #11810
(cherry picked from commit 1c53d4a070edbec8ad2d384ba0014d0eb6bae077)
---
src/basic/random-util.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index f7decf6..38f8180 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -37,6 +37,7 @@ int rdrand(unsigned long *ret) {
#if defined(__i386__) || defined(__x86_64__)
static int have_rdrand = -1;
+ unsigned long v;
unsigned char err;
if (have_rdrand < 0) {
@@ -56,7 +57,7 @@ int rdrand(unsigned long *ret) {
asm volatile("rdrand %0;"
"setc %1"
- : "=r" (*ret),
+ : "=r" (v),
"=qm" (err));
#if HAS_FEATURE_MEMORY_SANITIZER
@@ -66,6 +67,18 @@ int rdrand(unsigned long *ret) {
if (!err)
return -EAGAIN;
+ /* Apparently on some AMD CPUs RDRAND will sometimes (after a suspend/resume cycle?) report success
+ * via the carry flag but nonetheless return the same fixed value -1 in all cases. This appears to be
+ * a bad bug in the CPU or firmware. Let's deal with that and work-around this by explicitly checking
+ * for this special value (and also 0, just to be sure) and filtering it out. This is a work-around
+ * only however and something AMD really should fix properly. The Linux kernel should probably work
+ * around this issue by turning off RDRAND altogether on those CPUs. See:
+ * https://github.com/systemd/systemd/issues/11810 */
+ if (v == 0 || v == ULONG_MAX)
+ return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
+ "RDRAND returned suspicious value %lx, assuming bad hardware RNG, not using value.", v);
+
+ *ret = v;
return 0;
#else
return -EOPNOTSUPP;
...@@ -18,6 +18,7 @@ network-do-not-remove-rule-when-it-is-requested-by-existi.patch ...@@ -18,6 +18,7 @@ network-do-not-remove-rule-when-it-is-requested-by-existi.patch
pam-systemd-use-secure_getenv-rather-than-getenv.patch pam-systemd-use-secure_getenv-rather-than-getenv.patch
journal-remote-do-not-request-Content-Length-if-Transfer-.patch journal-remote-do-not-request-Content-Length-if-Transfer-.patch
systemctl-restore-systemctl-reboot-ARG-functionality.patch systemctl-restore-systemctl-reboot-ARG-functionality.patch
random-util-eat-up-bad-RDRAND-values-seen-on-AMD-CPUs.patch
debian/Use-Debian-specific-config-files.patch debian/Use-Debian-specific-config-files.patch
debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch debian/Bring-tmpfiles.d-tmp.conf-in-line-with-Debian-defaul.patch
debian/Make-run-lock-tmpfs-an-API-fs.patch debian/Make-run-lock-tmpfs-an-API-fs.patch
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment