bash/bash-3.2-rng.patch
Pete Graner eeaaae09ac - Update to the Improve bash $RANDOM pseudo RNG (bug #234906) now works
with subshells and make $RANDOM on demand thus reducing the amount of
    AVCs thrown.
2007-08-20 18:41:29 +00:00

185 lines
5.7 KiB
Diff

diff -up bash-3.2/config.h.in.rng.patch bash-3.2/config.h.in
--- bash-3.2/config.h.in.rng.patch 2007-08-20 13:42:49.000000000 +0200
+++ bash-3.2/config.h.in 2007-08-20 13:42:49.000000000 +0200
@@ -203,6 +203,8 @@
#define DEFAULT_MAIL_DIRECTORY "/var/spool/mail"
+#undef PATH_RANDOMDEV
+
/* Characteristics of the system's header files and libraries that affect
the compilation environment. */
@@ -817,6 +819,10 @@
/* Define if you have the wcwidth function. */
#undef HAVE_WCWIDTH
+#undef HAVE_RANDOM
+
+#undef HAVE_SRANDOM
+
/* Presence of certain system include files. */
/* Define if you have the <arpa/inet.h> header file. */
diff -up bash-3.2/configure.in.rng.patch bash-3.2/configure.in
--- bash-3.2/configure.in.rng.patch 2007-08-20 13:42:49.000000000 +0200
+++ bash-3.2/configure.in 2007-08-20 13:42:49.000000000 +0200
@@ -111,6 +111,7 @@ AC_ARG_WITH(gnu-malloc, AC_HELP_STRING([
AC_ARG_WITH(installed-readline, AC_HELP_STRING([--with-installed-readline], [use a version of the readline library that is already installed]), opt_with_installed_readline=$withval)
AC_ARG_WITH(purecov, AC_HELP_STRING([--with-purecov], [configure to postprocess with pure coverage]), opt_purecov=$withval)
AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval)
+AC_ARG_WITH(random, AC_HELP_STRING([--with-randomdev=path], [use specified random device instead of /dev/urandom]), opt_randomdev=$withval)
if test "$opt_bash_malloc" = yes; then
MALLOC_TARGET=malloc
@@ -152,6 +153,15 @@ if test -z "${DEBUGGER_START_FILE}"; the
DEBUGGER_START_FILE=${ac_default_prefix}/share/bashdb/bashdb-main.inc
fi
+if test "$opt_randomdev" = yes -o -z "$opt_randomdev"; then
+ opt_randomdev="/dev/urandom"
+elif test "$opt_randomdev" = no; then
+ opt_randomdev=
+fi
+if test -n "$opt_randomdev"; then
+ AC_DEFINE_UNQUOTED(PATH_RANDOMDEV, "$opt_randomdev", [Random device path.])
+fi
+
dnl optional shell features in config.h.in
opt_minimal_config=no
@@ -708,6 +718,8 @@ AC_CHECK_FUNCS(bcopy bzero confstr fnmat
setenv setlinebuf setlocale setvbuf siginterrupt strchr \
sysconf tcgetattr times ttyname tzset unsetenv)
+AC_CHECK_FUNCS(random srandom)
+
AC_CHECK_FUNCS(vsnprintf snprintf vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
diff -up bash-3.2/variables.c.rng.patch bash-3.2/variables.c
--- bash-3.2/variables.c.rng.patch 2006-09-08 19:33:32.000000000 +0200
+++ bash-3.2/variables.c 2007-08-20 16:16:56.000000000 +0200
@@ -42,6 +42,11 @@
#include "bashansi.h"
#include "bashintl.h"
+#if defined (PATH_RANDOMDEV)
+# include <errno.h>
+# include "filecntl.h"
+#endif
+
#include "shell.h"
#include "flags.h"
#include "execute_cmd.h"
@@ -182,7 +187,8 @@ static SHELL_VAR *get_seconds __P((SHELL
static SHELL_VAR *init_seconds_var __P((void));
static int brand __P((void));
-static void sbrand __P((unsigned long)); /* set bash random number generator. */
+static void sbrand __P((unsigned int)); /* set bash random number generator. */
+static void seed_random __P((void)); /* seed the generator randomly */
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *get_random __P((SHELL_VAR *));
@@ -494,9 +500,6 @@ initialize_shell_variables (env, privmod
}
#endif /* HISTORY */
- /* Seed the random number generator. */
- sbrand (dollar_dollar_pid + shell_start_time);
-
/* Handle some "special" variables that we may have inherited from a
parent shell. */
if (interactive_shell)
@@ -1143,9 +1146,11 @@ init_seconds_var ()
}
/* The random number seed. You can change this by setting RANDOM. */
+#if !defined (HAVE_RANDOM)
static unsigned long rseed = 1;
+#endif
static int last_random_value;
-static int seeded_subshell = 0;
+static int seeded_subshell = -1;
/* A linear congruential random number generator based on the example
one in the ANSI C standard. This one isn't very good, but a more
@@ -1155,28 +1160,58 @@ static int seeded_subshell = 0;
static int
brand ()
{
+#if defined (HAVE_RANDOM)
+ unsigned int rseed;
+ rseed = random();
+#else
rseed = rseed * 1103515245 + 12345;
+#endif
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
}
/* Set the random number generator seed to SEED. */
static void
sbrand (seed)
- unsigned long seed;
+ unsigned int seed;
{
+#if defined (HAVE_RANDOM)
+ srandom((unsigned int)seed);
+#else
rseed = seed;
+#endif
last_random_value = 0;
}
+static void
+seed_random ()
+{
+ unsigned int seed;
+#if defined (PATH_RANDOMDEV)
+ int fd;
+ int rv;
+ if ((rv = fd = open (PATH_RANDOMDEV, O_RDONLY)) != -1) {
+ while ((rv = read(fd, &seed, sizeof(seed))) != sizeof(seed) && errno == EINTR);
+ close (fd);
+ }
+ if (rv != sizeof(seed)) {
+#endif
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ seed = (unsigned int)tv.tv_sec + (unsigned int)tv.tv_usec + getpid();
+#if defined (PATH_RANDOMDEV)
+ }
+#endif
+ sbrand (seed);
+}
+
static SHELL_VAR *
assign_random (self, value, unused)
SHELL_VAR *self;
char *value;
arrayind_t unused;
{
- sbrand (strtoul (value, (char **)NULL, 10));
- if (subshell_environment)
- seeded_subshell = 1;
+ sbrand ((unsigned int)strtoul (value, (char **)NULL, 10));
+ seeded_subshell = subshell_level;
return (self);
}
@@ -1186,10 +1221,10 @@ get_random_number ()
int rv;
/* Reset for command and process substitution. */
- if (subshell_environment && seeded_subshell == 0)
+ if (seeded_subshell < subshell_level)
{
- sbrand (rseed + getpid() + NOW);
- seeded_subshell = 1;
+ seed_random ();
+ seeded_subshell = subshell_level;
}
do