1 Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
3 Initial Package Version: 2.11.1
4 Upstream Status: Not Submitted
5 Origin: Based on http://www.uclibc.org/cgi-bin/viewcvs.cgi/trunk/uClibc/libc/
6 misc/internals/tempname.c?rev=8887&r1=5747&r2=8887
8 Use /dev/urandom exclusively with __gen_tempname(), for the mktemp/tmpnam
9 family, instead of hp-timing, gettimeofday(), or getpid(). return -1 if
10 /dev/urandom does not open.
12 diff -Naur glibc-2.11.1.orig/sysdeps/posix/tempname.c glibc-2.11.1/sysdeps/posix/tempname.c
13 --- glibc-2.11.1.orig/sysdeps/posix/tempname.c 2009-12-08 20:10:20.000000000 +0000
14 +++ glibc-2.11.1/sysdeps/posix/tempname.c 2010-02-19 17:36:44.000000000 +0000
19 -#if HAVE_SYS_TIME_H || _LIBC
20 -# include <sys/time.h>
23 #if HAVE_STDINT_H || _LIBC
27 # define struct_stat64 struct stat64
29 # define struct_stat64 struct stat
30 -# define __getpid getpid
31 -# define __gettimeofday gettimeofday
32 # define __mkdir mkdir
34 # define __open64 open
35 +# define __close close
37 # define __lxstat64(version, path, buf) lstat (path, buf)
38 # define __xstat64(version, path, buf) stat (path, buf)
41 # define __secure_getenv getenv
45 -# include <hp-timing.h>
47 -# define RANDOM_BITS(Var) \
48 - if (__builtin_expect (value == UINT64_C (0), 0)) \
50 - /* If this is the first time this function is used initialize \
51 - the variable we accumulate the value in to some somewhat \
52 - random value. If we'd not do this programs at startup time \
53 - might have a reduced set of possible names, at least on slow \
55 - struct timeval tv; \
56 - __gettimeofday (&tv, NULL); \
57 - value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \
63 /* Use the widest available unsigned type if uint64_t is not
64 available. The algorithm below extracts a number less than 62**6
65 (approximately 2**35.725) from uint64_t, so ancient hosts where
67 static const char letters[] =
68 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
70 +static unsigned int fillrand(unsigned char *buf, unsigned int len)
73 + unsigned int result = -1;
74 + fd = __open("/dev/urandom", O_RDONLY|O_NONBLOCK|O_NOCTTY);
77 + result = __read(fd, buf, len);
83 /* Generate a temporary file name based on TMPL. TMPL must match the
84 rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
85 The name constructed does not exist at the time of the call to
87 at the time of the call.
88 __GT_FILE: create the file using open(O_CREAT|O_EXCL)
89 and return a read-write fd. The file is mode 0600.
90 - __GT_DIR: create a directory, which will be mode 0700.
91 + __GT_DIR: create a directory, which will be mode 0700. */
93 - We use a clever algorithm to get hard-to-predict names. */
95 __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
100 static uint64_t value;
101 uint64_t random_time_bits;
104 int save_errno = errno;
106 + unsigned char randomness[6];
109 /* A lower bound on the number of temporary files to attempt to
110 generate. The maximum total number of temporary file names that
111 @@ -260,39 +251,20 @@
112 /* This is where the Xs start. */
113 XXXXXX = &tmpl[len - 6 - suffixlen];
115 - /* Get some more or less random data. */
117 - RANDOM_BITS (random_time_bits);
119 -# if HAVE_GETTIMEOFDAY || _LIBC
122 - __gettimeofday (&tv, NULL);
123 - random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
126 - random_time_bits = time (NULL);
129 - value += random_time_bits ^ __getpid ();
130 + /* Get some random data, and die otherwise. */
131 + if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness))
133 + __set_errno (ENODEV);
136 + for (i = 0 ; i < sizeof(randomness) ; i++)
138 + k = ((randomness[i]) % 62);
139 + XXXXXX[i] = letters[k];
142 for (count = 0; count < attempts; value += 7777, ++count)
144 - uint64_t v = value;
146 - /* Fill in the random bits. */
147 - XXXXXX[0] = letters[v % 62];
149 - XXXXXX[1] = letters[v % 62];
151 - XXXXXX[2] = letters[v % 62];
153 - XXXXXX[3] = letters[v % 62];
155 - XXXXXX[4] = letters[v % 62];
157 - XXXXXX[5] = letters[v % 62];