Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

random-util: eat up bad RDRAND values seen on AMD CPUs #12536

Merged
merged 1 commit into from May 14, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

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
  • Loading branch information...
poettering committed May 10, 2019
commit 1c53d4a070edbec8ad2d384ba0014d0eb6bae077
@@ -35,6 +35,7 @@ int rdrand(unsigned long *ret) {

#if defined(__i386__) || defined(__x86_64__)
static int have_rdrand = -1;
unsigned long v;
uint8_t success;

if (have_rdrand < 0) {
@@ -59,12 +60,24 @@ int rdrand(unsigned long *ret) {

asm volatile("rdrand %0;"
"setc %1"
: "=r" (*ret),
: "=r" (v),
"=qm" (success));
msan_unpoison(&success, sizeof(success));
if (!success)
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;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.