Use arc4random() for mkstemp/mkdtemp if available. If not, try to

seed from /dev/urandom before falling back to the gettimeofday seed.
This commit is contained in:
Todd C. Miller
2014-10-31 06:57:19 -06:00
parent ccc210eddb
commit 2040d4dde5
4 changed files with 45 additions and 20 deletions

View File

@@ -52,6 +52,9 @@
/* Define to 1 if you use AIX general authentication. */ /* Define to 1 if you use AIX general authentication. */
#undef HAVE_AIXAUTH #undef HAVE_AIXAUTH
/* Define to 1 if you have the `arc4random' function. */
#undef HAVE_ARC4RANDOM
/* Define to 1 if you have the `asprintf' function. */ /* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF #undef HAVE_ASPRINTF

2
configure vendored
View File

@@ -18401,7 +18401,7 @@ fi
done done
if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then 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 : do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@@ -2520,7 +2520,7 @@ AC_CHECK_FUNCS(closefrom, [], [AC_LIBOBJ(closefrom)
]) ])
AC_CHECK_FUNCS(mkstemps mkdtemp, [], [break]) AC_CHECK_FUNCS(mkstemps mkdtemp, [], [break])
if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then 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) AC_LIBOBJ(mktemp)
# If either mkdtemp() or mkstemps() is missing, replace both. # If either mkdtemp() or mkstemps() is missing, replace both.
SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkstemps) SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkstemps)

View File

@@ -50,35 +50,57 @@
#define INT_MAX 0x7fffffff #define INT_MAX 0x7fffffff
#endif #endif
#ifdef HAVE_RANDOM #if defined(HAVE_ARC4RANDOM)
# define RAND random # define RAND() arc4random()
# define SRAND srandom
# define SEED_T unsigned int # 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 #else
# ifdef HAVE_LRAND48 # define RAND() rand()
# define RAND lrand48 # define SRAND(_x) srand((_x))
# define SRAND srand48 # define SEED_T unsigned int
# define SEED_T long
# else
# define RAND rand
# define SRAND srand
# define SEED_T unsigned int
# endif
#endif #endif
static void static void
seed_random(void) seed_random(void)
{ {
SEED_T seed; #ifdef SRAND
struct timeval tv; 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); fd = open("/dev/urandom", O_RDONLY);
seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 + if (fd != -1) {
(getpid() % 1000) * 983; 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); SRAND(seed);
#endif
} }
static unsigned int static unsigned int
@@ -98,7 +120,7 @@ static int
mktemp_internal(char *path, int slen, int mode) mktemp_internal(char *path, int slen, int mode)
{ {
char *start, *cp, *ep; char *start, *cp, *ep;
const char *tempchars = TEMPCHARS; const char tempchars[] = TEMPCHARS;
unsigned int r, tries; unsigned int r, tries;
int fd; int fd;