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 78bc2727f7
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.
This commit is contained in:
Nik Bougalis
2022-05-10 09:36:12 -07:00
committed by manojsdoshi
parent b68a66928c
commit 7ca1f78446

View File

@@ -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<std::uint8_t*>(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
}