Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

Commit

Permalink
fix: use a safer token to workaround libstdc++ bug (#272)
Browse files Browse the repository at this point in the history
The workaround put in place in #208 does not work with g++-9.3.1 on
Fedora:31. Despite this being a "newer" version of libstdc++, it does
not support `rdrand` as a token for `std::random_device` maybe because
the CPU specific tokens are not enabled.

For now, use `/dev/urandom` which seems to be supported on all Linux
distros. On other platforms we continue to use the default constructor
for `std::random_device`.

It might be possible to refine this and detect, at run-time, if `rdrand`
is supported, but that seems like an improvement that can wait a little
bit.
  • Loading branch information
coryan committed Apr 1, 2020
1 parent e1a58fb commit f3bddd1
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions google/cloud/internal/random.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,20 @@ std::vector<unsigned int> FetchEntropy(std::size_t desired_bits) {
// [4]: https://linux.die.net/man/3/arc4random
// [5]: https://en.wikipedia.org/wiki/NaCl_(software)
//
#if defined(__GLIBCXX__) && __GLIBCXX__ >= 20200128
#if defined(__linux) && defined(__GLIBCXX__) && __GLIBCXX__ >= 20200128
// Workaround for a libstd++ bug:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94087
// we cannot simply use `rdrand` everywhere because this is library and
// version specific, i.e., other standard C++ libraries do not support
// `rdrand`, and even older versions of libstdc++ do not support `rdrand`.
std::random_device rd("rdrand");
// I (@coryan) would like to use `rdrand` as the token, but:
// - `rdrand` is not supported by all versions of libstdc++
// - even for the versions that do support it, that is CPU specific
// - I know of no reliable way to detect if the library version supports
// `rdrand` (other than trying and getting an exception), for
// example:
// * __GLIBCXX__ is 2020318 on Fedora:31 with g++-9.3.1, but it does
// *not* support `rdrand`
// * __GLIBCXX__ is 20200306 on openSUSE/Tumbleweed, with g++-9.2.1,
// but it *does* support `rdrand`
std::random_device rd("/dev/urandom");
#else
std::random_device rd;
#endif // defined(__GLIBCXX__) && __GLIBCXX__ >= 20200128
Expand Down

0 comments on commit f3bddd1

Please sign in to comment.