]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
shuf: fix randomness bug
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Aug 2024 05:31:20 +0000 (22:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 4 Aug 2024 06:22:53 +0000 (23:22 -0700)
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.

NEWS
THANKS.in
gl/lib/randread.c

diff --git a/NEWS b/NEWS
index 6251a2f68681ca468e7e78bcc9ca7cfd2d70664e..2da258c9dd9459445db8b7e64a29b273b9002731 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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".]
 
index 17f9d9c693c0867b5402b77fc18b942173c7a393..57ace387e0a1b5d3fdab94a73e2bac3a6be1f9d9 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -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
index cbee224bb011ec43cbd59be57bffd91a22984660..43c0cf09f3c137862113fefa9553c58e3ce70172 100644 (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);