diff --git a/AK/Random.h b/AK/Random.h index 1fc7c81c038..80b636b30c6 100644 --- a/AK/Random.h +++ b/AK/Random.h @@ -9,10 +9,7 @@ #include #include #include - -#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID) -# include -#endif +#include #if defined(__unix__) # include @@ -22,10 +19,6 @@ # include #endif -#if defined(AK_OS_WINDOWS) -# include -#endif - namespace AK { inline void fill_with_random([[maybe_unused]] void* buffer, [[maybe_unused]] size_t length) @@ -33,13 +26,35 @@ inline void fill_with_random([[maybe_unused]] void* buffer, [[maybe_unused]] siz #if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID) arc4random_buf(buffer, length); #elif defined(OSS_FUZZ) -#elif defined(__unix__) or defined(AK_OS_MACOS) - [[maybe_unused]] int rc = getentropy(buffer, length); #else - char* char_buffer = static_cast(buffer); - for (size_t i = 0; i < length; i++) { - char_buffer[i] = rand(); + auto fill_with_random_fallback = [&]() { + char* char_buffer = static_cast(buffer); + for (size_t i = 0; i < length; i++) + char_buffer[i] = rand(); + }; + +# if defined(__unix__) or defined(AK_OS_MACOS) + // The maximum permitted value for the getentropy length argument. + static constexpr size_t getentropy_length_limit = 256; + + auto iterations = length / getentropy_length_limit; + auto remainder = length % getentropy_length_limit; + auto address = reinterpret_cast(buffer); + + for (size_t i = 0; i < iterations; ++i) { + if (getentropy(reinterpret_cast(address), getentropy_length_limit) != 0) { + fill_with_random_fallback(); + return; + } + + address += getentropy_length_limit; } + + if (remainder == 0 || getentropy(reinterpret_cast(address), remainder) == 0) + return; +# endif + + fill_with_random_fallback(); #endif }