On Thursday April 26 2007 04:12, Tha D0od wrote:
> This is really interesting.  I tried out the RANDOM thing you mentioned,
> and played with it a little bit.  At least in my case, I got the same
> first result as you after setting RANDOM to 1.  Then I unset it.  After
> I unset it, RANDOM no longer returned random numbers.  It just returned
> the value I set it to.  I suppose that's what the man page means when it
> says it 'loses its special properties.'  I'm not sure if you can get it
> to generating random numbers again after you unset it, but I haven't
> really did anything too involved to verify this.

In bash-3.2/variables.c we have:

static int
brand ()
{
  rseed = rseed * 1103515245 + 12345;
  return ((unsigned int)((rseed >> 16) & 32767));       /* was % 32768 */
}

the brand() function is used for the $RANDOM initialization. As you can see 
the math is pretty simple, and it's beyond the scope of Bash to make it more 
complex, and even if it were more complex it probably wouldn't help.. it 
depends more on the seed itself.

Replace with this:
  rseed = (unsigned int) (labs(arc4random()) & 32767);
  return rseed;

and now RANDOM=1 has no effect, $RANDOM will always change because the return 
value of brand() is not consistant.

I submitted a patch to bugs-bash today, which is basically:

+#if defined(HAVE_ARC4RANDOM)
+      sbrand (arc4random());
+#else
       sbrand (rseed + getpid() + NOW);
+#endif

in the get_random_number() function, plus some arc4random() checks 
in ./configure to keep things portable. This does not change the behavior 
of 'RANDOM=1 ; echo $RANDOM', it just uses arc4random() instead of getpid(), 
for the uninitialized RANDOM stirring.

If we want to completely break 'RANDOM=1 ; echo $RANDOM' then the stirring 
routines can be removed all together, and $RANDOM will always be different 
and there won't be any way to affect it from Bash (I think this is the best 
idea).

The shell $RANDOM variable do not seem to be a Posix standard, however for 
some reason (probably before /dev/urandom became popular) it is currently 
accepted that users are able to seed RANDOM themselves.

I think if you want a cheaper method of making random numbers than using 
arc4random(), then make your own shell-function to stir your seed. However, 
breaking 'RANDOM=1 ; echo $RANDOM' probably means the patch will never be 
accepted upstream.

It is also generally accepted to not use $RANDOM from the shell for anything 
important, and this environment variable has very little use in modern 
systems. Use /dev/{e,u}random instead. Despite this, using arc4random() for 
uninitialized $RANDOM is still valid.

This comes down to how much we're willing to trust $RANDOM, and why. We can 
not count on it being random on unpatched systems, and this would make 
scripts which depend on real random $RANDOM dangerous on non-patched systems. 
It is not difficult to use /dev/?random instead, in a shell script.

robert

Attachment: pgp0uJnkZtjck.pgp
Description: PGP signature

-- 
http://linuxfromscratch.org/mailman/listinfo/hlfs-dev
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to