]> granicus.if.org Git - sudo/commitdiff
Use arc4random() for mkstemp/mkdtemp if available. If not, try to
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 31 Oct 2014 12:57:19 +0000 (06:57 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 31 Oct 2014 12:57:19 +0000 (06:57 -0600)
seed from /dev/urandom before falling back to the gettimeofday seed.

config.h.in
configure
configure.ac
lib/util/mktemp.c

index 0acb6d1fed3c688656493b18162c98f95710766a..0b0234a1be757c850ca9f59f65cd9d943e166081 100644 (file)
@@ -52,6 +52,9 @@
 /* Define to 1 if you use AIX general authentication. */
 #undef HAVE_AIXAUTH
 
+/* Define to 1 if you have the `arc4random' function. */
+#undef HAVE_ARC4RANDOM
+
 /* Define to 1 if you have the `asprintf' function. */
 #undef HAVE_ASPRINTF
 
index b0b21aab7058b5411aa1f97dd6d996e31ea5b9a0..7310c3f1d9aad2c8fbbc1ab8ad8ef46e00170302 100755 (executable)
--- a/configure
+++ b/configure
@@ -18401,7 +18401,7 @@ fi
 done
 
 if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
-    for ac_func in random lrand48
+    for ac_func in arc4random random lrand48
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 546b981267f981b9c11f7596c4924c86271fadce..f4fa0c7755c9fcd662cf381f9eb8e66f8ede15e5 100644 (file)
@@ -2520,7 +2520,7 @@ AC_CHECK_FUNCS(closefrom, [], [AC_LIBOBJ(closefrom)
 ])
 AC_CHECK_FUNCS(mkstemps mkdtemp, [], [break])
 if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
-    AC_CHECK_FUNCS(random lrand48, [break])
+    AC_CHECK_FUNCS(arc4random random lrand48, [break])
     AC_LIBOBJ(mktemp)
     # If either mkdtemp() or mkstemps() is missing, replace both.
     SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkstemps)
index 87ed760fa214d203e2fe412c90582c91a65dd1a0..50ce6ccda4fa045bbd620f468b543d4279fa6aa3 100644 (file)
 #define INT_MAX        0x7fffffff
 #endif
 
-#ifdef HAVE_RANDOM
-# define RAND          random
-# define SRAND         srandom
+#if defined(HAVE_ARC4RANDOM)
+# define RAND()                arc4random()
 # define SEED_T                unsigned int
+#elif defined(HAVE_RANDOM)
+# define RAND()                random()
+# define SRAND(_x)     srandom((_x))
+# define SEED_T                unsigned int
+#elif defined(HAVE_LRAND48)
+# define RAND()                lrand48()
+# define SRAND(_x)     srand48((_x))
+# define SEED_T                long
 #else
-# ifdef HAVE_LRAND48
-#  define RAND         lrand48
-#  define SRAND                srand48
-#  define SEED_T       long
-# else
-#  define RAND         rand
-#  define SRAND                srand
-#  define SEED_T       unsigned int
-# endif
+# define RAND()                rand()
+# define SRAND(_x)     srand((_x))
+# define SEED_T                unsigned int
 #endif
 
 static void
 seed_random(void)
 {
-       SEED_T seed;
+#ifdef SRAND
        struct timeval tv;
+       SEED_T seed;
+       int fd;
 
        /*
-        * Seed from time of day and process id multiplied by small primes.
+        * Seed from /dev/urandom if possible.
         */
-       (void) gettimeofday(&tv, NULL);
-       seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
-           (getpid() % 1000) * 983;
+       fd = open("/dev/urandom", O_RDONLY);
+       if (fd != -1) {
+           ssize_t nread;
+
+           do {
+               nread = read(fd, &seed, sizeof(seed));
+           } while (nread == -1 && errno == EINTR);
+           close(fd);
+           if (nread != (ssize_t)sizeof(seed))
+               fd = -1;
+       }
+
+       /*
+        * If no /dev/urandom, seed from time of day and process id
+        * multiplied by small primes.
+        */
+       if (fd == -1) {
+           (void) gettimeofday(&tv, NULL);
+           seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
+               (getpid() % 1000) * 983;
+       }
        SRAND(seed);
+#endif
 }
 
 static unsigned int
@@ -98,7 +120,7 @@ static int
 mktemp_internal(char *path, int slen, int mode)
 {
        char *start, *cp, *ep;
-       const char *tempchars = TEMPCHARS;
+       const char tempchars[] = TEMPCHARS;
        unsigned int r, tries;
        int fd;