From 7ca1f78446e1ec940dd4af85be3a1ab61719d636 Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Tue, 10 May 2022 09:36:12 -0700 Subject: [PATCH] Ensure that `rngfill` returns the requested amount of randomness: One of the two versions of the `rngfill` function accepts a pointer to a buffer and a size (in bytes). The function aims to fill the provided `buffer` with `size` random bytes. It does this in chunks of 8 bytes, for long as possible, and then fills any left-over gap one byte at a time. To avoid an annoying and incorrect warning about a potential buffer overflow in the "trailing write", commit 78bc2727f707485d59364d7497dec1f464c2d356 used a `#pragma` to instruct the compiler to not generate the incorrect diagnostic. Unfortunately, this change _also_ eliminated the trailing write code, which means that, under some cases, the `rngfill` function would generate between 1 and 7 fewer random bytes than requested. This problem would only manifest on builds that do not define `__GNUC__` which, as of this writing, means MSVC. --- src/ripple/beast/utility/rngfill.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ripple/beast/utility/rngfill.h b/src/ripple/beast/utility/rngfill.h index d906a66a0b..cf8b7bbeb4 100644 --- a/src/ripple/beast/utility/rngfill.h +++ b/src/ripple/beast/utility/rngfill.h @@ -32,6 +32,7 @@ void rngfill(void* buffer, std::size_t bytes, Generator& g) { using result_type = typename Generator::result_type; + while (bytes >= sizeof(result_type)) { auto const v = g(); @@ -39,15 +40,22 @@ rngfill(void* buffer, std::size_t bytes, Generator& g) buffer = reinterpret_cast(buffer) + sizeof(v); bytes -= sizeof(v); } + + assert(bytes < sizeof(result_type)); + #ifdef __GNUC__ // gcc 11.1 (falsely) warns about an array-bounds overflow in release mode. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Warray-bounds" +#endif + if (bytes > 0) { auto const v = g(); std::memcpy(buffer, &v, bytes); } + +#ifdef __GNUC__ #pragma GCC diagnostic pop #endif }