From 702cae1e762dc6f2f9d31777db04e1adbdb36697 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 1 Jun 2021 18:32:49 -0700 Subject: Export of internal Abseil changes -- 2c81c02d2b68303134e777f31921679ab87a2639 by Derek Mauro : Use getentropy() to get seed material when using glibc >= 2.25 getentropy() uses the getrandom syscall on Linux to avoid file descriptors. It is never interputed (EINTR) and uses the same source as /dev/urandom. https://man7.org/linux/man-pages/man3/getentropy.3.html getrandom has been in the Linux since kernel 3.17 When unavailable (ENOSYS), fallback to /dev/urandom. PiperOrigin-RevId: 376962620 -- 81cd41372a04eda400a2e3be53c239c0dac6bdf3 by Abseil Team : Make FunctionRef no longer have -Wdeprecated-copy warnings from Clang by defaulting the copy constructor. This is needed because the assignment operator is deleted. Fixes #948 PiperOrigin-RevId: 376928548 GitOrigin-RevId: 2c81c02d2b68303134e777f31921679ab87a2639 Change-Id: I0abb18052ffff5dd1448f0b68edbb668045335f0 --- absl/functional/function_ref.h | 1 + absl/random/internal/seed_material.cc | 40 ++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'absl') diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h index 6e03ac2e..5790a652 100644 --- a/absl/functional/function_ref.h +++ b/absl/functional/function_ref.h @@ -122,6 +122,7 @@ class FunctionRef { // To help prevent subtle lifetime bugs, FunctionRef is not assignable. // Typically, it should only be used as an argument type. FunctionRef& operator=(const FunctionRef& rhs) = delete; + FunctionRef(const FunctionRef& rhs) = default; // Call the underlying object. R operator()(Args... args) const { diff --git a/absl/random/internal/seed_material.cc b/absl/random/internal/seed_material.cc index 4d38a574..0fcba509 100644 --- a/absl/random/internal/seed_material.cc +++ b/absl/random/internal/seed_material.cc @@ -50,6 +50,12 @@ #endif +#if defined(__GLIBC__) && \ + (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) +// glibc >= 2.25 has getentropy() +#define ABSL_RANDOM_USE_GET_ENTROPY 1 +#endif + #if defined(ABSL_RANDOM_USE_BCRYPT) #include @@ -122,8 +128,29 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span values) { #else +#if defined(ABSL_RANDOM_USE_GET_ENTROPY) +// On *nix, use getentropy() if supported. Note that libc may support +// getentropy(), but the kernel may not, in which case this function will return +// false. +bool ReadSeedMaterialFromGetEntropy(absl::Span values) { + auto buffer = reinterpret_cast(values.data()); + size_t buffer_size = sizeof(uint32_t) * values.size(); + while (buffer_size > 0) { + // getentropy() has a maximum permitted length of 256. + size_t to_read = std::min(buffer_size, 256); + int result = getentropy(buffer, to_read); + if (result < 0) { + return false; + } + buffer += to_read; + buffer_size -= to_read; + } + return true; +} +#endif // defined(ABSL_RANDOM_GETENTROPY) + // On *nix, read entropy from /dev/urandom. -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span values) { +bool ReadSeedMaterialFromDevURandom(absl::Span values) { const char kEntropyFile[] = "/dev/urandom"; auto buffer = reinterpret_cast(values.data()); @@ -150,6 +177,17 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span values) { return success; } +bool ReadSeedMaterialFromOSEntropyImpl(absl::Span values) { +#if defined(ABSL_RANDOM_USE_GET_ENTROPY) + if (ReadSeedMaterialFromGetEntropy(values)) { + return true; + } +#endif + // Libc may support getentropy, but the kernel may not, so we still have + // to fallback to ReadSeedMaterialFromDevURandom(). + return ReadSeedMaterialFromDevURandom(values); +} + #endif } // namespace -- cgit v1.2.3