Subject: bug#6683: closed (Re: bug#6683: mktemp foo.XXXXXXXXXXX is not sufficiently random)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 08 Aug 2011 07:41:03 +0000

Your bug report

#6683: mktemp foo.XXXXXXXXXXX is not sufficiently random

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
6683: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6683
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#6683: mktemp foo.XXXXXXXXXXX is not sufficiently random
From: Paul Eggert <[email-masked]>
To: Jim Meyering <[email-masked]>
Cc: [email-masked]
Date: Mon, 08 Aug 2011 00:39:30 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

On 08/07/2011 10:04 AM, Jim Meyering wrote:

> Yes, please do.

OK, thanks, I installed the one-line change as change to the diff.
This is the first time I've updated a diff file in a while (ever?),
so I hope I did it right.  I'm marking the bug done.

>From 8e2767a3f0c279d355f067e53be2c63173959eb1 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Mon, 8 Aug 2011 00:29:46 -0700
Subject: [PATCH] mktemp: stir in enough entropy (Bug#6683)

* gl/lib/tempname.c.diff (gen_tempname_len):
Use x_suffix_len bytes' worth of entropy, not 8 bytes.
---
 gl/lib/tempname.c.diff |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gl/lib/tempname.c.diff b/gl/lib/tempname.c.diff
index fcacf53..3e30c97 100644
--- a/gl/lib/tempname.c.diff
+++ b/gl/lib/tempname.c.diff
@@ -100,7 +100,7 @@ index 2da5afe..562955a 100644
 -  }
 -#endif
 -  value += random_time_bits ^ __getpid ();
-+  rand_src = randint_all_new (NULL, 8);
++  rand_src = randint_all_new (NULL, x_suffix_len);
 +  if (! rand_src)
 +    return -1;
 
-- 
1.7.4.4

Subject: mktemp foo.XXXXXXXXXXX is not sufficiently random
From: Paul Eggert <[email-masked]>
To: Bug Coreutils <[email-masked]>
Date: Tue, 20 Jul 2010 10:21:11 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

While looking at the random-number stuff I found a theoretical
randomness bug in mktemp.  The mktemp command currently uses 8 bytes
of randomness to generate a file name, so with an invocation like
this:

$ mktemp foo.XXXXXXXXXXX

the file name is not sufficiently random.  There are 62 possibilities
for each X, so one needs log2(62**11) random bits to generate a random
11-character value for the Xs, which is about 65.5 bits, but we are
generating only 64 bits.  The more Xs, the more randomness is needed,
so the bug gets more "serious" as the number of Xs grows.

Here's a simple patch to fix this.  Should I install this by
generating a new gl/lib/tempname.c.diff by hand, and pushing that?

--- old/tempname.c	2010-07-20 09:41:36.774229000 -0700
+++ new/tempname.c	2010-07-20 10:14:33.391452000 -0700
@@ -245,7 +245,7 @@ gen_tempname_len (char *tmpl, int suffix
   XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
 
   /* Get some more or less random data.  */
-  rand_src = randint_all_new (NULL, 8);
+  rand_src = randint_all_new (NULL, x_suffix_len);
   if (! rand_src)
     return -1;

Here's a fancier patch that uses fewer random bits, but on
futher thought I don't think it's worth the extra machine
instructions for a purely-theoretical bug:

--- old/tempname.c	2010-07-20 09:41:36.774229000 -0700
+++ new/tempname.c	2010-07-20 09:45:00.685972000 -0700
@@ -19,6 +19,7 @@
 
 #if !_LIBC
 # include <config.h>
+# include <limits.h>
 # include "tempname.h"
 # include "randint.h"
 #endif
@@ -189,6 +190,17 @@ check_x_suffix (char const *s, size_t le
 static const char letters[] =
 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
+/* Upper bound on the number bytes of random information needed to
+   generate N random letters.  There are 62 letters, and 2**6 is 64,
+   so 6N bits = 6N/CHAR_BIT bytes is an upper bound.  Return ceil (6.0
+   * N / CHAR_BIT) without rounding error or overflow.  */
+static size_t
+randomness_bound (size_t n)
+{
+  return ((n / CHAR_BIT) * 6
+	  + ((n % CHAR_BIT) * 6 + CHAR_BIT - 1) / CHAR_BIT);
+}
+
 /* Generate a temporary file name based on TMPL.  TMPL must match the
    rules for mk[s]temp (i.e. end in at least X_SUFFIX_LEN "X"s,
    possibly with a suffix).
@@ -245,7 +257,7 @@ gen_tempname_len (char *tmpl, int suffix
   XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
 
   /* Get some more or less random data.  */
-  rand_src = randint_all_new (NULL, 8);
+  rand_src = randint_all_new (NULL, randomness_bound (x_suffix_len));
   if (! rand_src)
     return -1;