shuf: fix randomness bug

Problem reported by Daniel Carpenter <https://bugs.gnu.org/72445>.
* gl/lib/randread.c (randread_new): Fill the ISAAC buffer
instead of storing at most BYTES_BOUND bytes into it.
This commit is contained in:
Paul Eggert 2024-08-03 22:31:20 -07:00
parent 1ae98dbda7
commit bfbb3ec7f7
3 changed files with 15 additions and 1 deletions

3
NEWS
View File

@ -16,6 +16,9 @@ GNU coreutils NEWS -*- outline -*-
have exited with a "Function not implemented" error.
[bug introduced in coreutils-8.28]
'shuf' generates more-random output when the output is small.
[bug introduced in coreutils-8.6]
'tail -c 4096 /dev/zero' no longer loops forever.
[This bug was present in "the beginning".]

View File

@ -140,6 +140,7 @@ Dameon G. Rogers dgr03@uark.edu
Dan Hagerty hag@gnu.ai.it.edu
Dan Pascu dan@services.iiruc.ro
Daniel Bergstrom noa@melody.se
Daniel Carpenter dansebpub@gmail.com
Daniel Mach dmach@redhat.com
Daniel P. Berrangé berrange@redhat.com
Daniel Stavrovski d@stavrovski.net

View File

@ -189,9 +189,19 @@ randread_new (char const *name, size_t bytes_bound)
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
else
{
/* Fill the ISAAC buffer. Although it is tempting to read at
most BYTES_BOUND bytes, this is incorrect for two reasons.
First, BYTES_BOUND is just an estimate.
Second, even if the estimate is correct
ISAAC64 poorly randomizes when BYTES_BOUND is small
and just the first few bytes of s->buf.isaac.state.m
are random while the other bytes are all zero. See:
Aumasson J-P. On the pseudo-random generator ISAAC.
Cryptology ePrint Archive. 2006;438.
<https://eprint.iacr.org/2006/438>. */
s->buf.isaac.buffered = 0;
if (! get_nonce (s->buf.isaac.state.m,
MIN (sizeof s->buf.isaac.state.m, bytes_bound)))
sizeof s->buf.isaac.state.m))
{
int e = errno;
randread_free_body (s);