On Wed, Sep 20, 2017 at 11:39:26PM +0300, Alexander Monakov wrote:
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -239,7 +239,7 @@ announce_function (tree decl)
>      }
>  }
>  
> -/* Initialize local_tick with a random number or -1 if
> +/* Initialize local_tick with the time of day, or -1 if
>     flag_random_seed is set.  */
>  
>  static void
> @@ -247,19 +247,6 @@ init_local_tick (void)
>  {
>    if (!flag_random_seed)
>      {
> -      /* Try urandom first. Time of day is too likely to collide. 
> -      In case of any error we just use the local tick. */
> -
> -      int fd = open ("/dev/urandom", O_RDONLY);
> -      if (fd >= 0)
> -        {
> -          if (read (fd, &random_seed, sizeof (random_seed))
> -              != sizeof (random_seed))
> -            random_seed = 0;
> -          close (fd);
> -        }
> -
> -      /* Now get the tick anyways  */
>  #ifdef HAVE_GETTIMEOFDAY
>        {
>       struct timeval tv;
> @@ -280,34 +267,33 @@ init_local_tick (void)
>      local_tick = -1;
>  }

Why isn't init_local_tick done at the get_random_seed time too?
I.e. inlined into get_random_seed by hand like you've done for
init_random_seed?

>  /* Obtain the random_seed.  Unless NOINIT, initialize it if
>     it's not provided in the command line.  */
>  
>  HOST_WIDE_INT
>  get_random_seed (bool noinit)
>  {
> -  if (!flag_random_seed && !noinit)
> -    init_random_seed ();
> +  if (!random_seed && !noinit)
> +    {
> +      int fd = open ("/dev/urandom", O_RDONLY);
> +      if (fd >= 0)
> +        {
> +          if (read (fd, &random_seed, sizeof (random_seed))
> +              != sizeof (random_seed))
> +            random_seed = 0;
> +          close (fd);
> +        }
> +      if (!random_seed)
> +     random_seed = local_tick ^ getpid ();

If one is unlucky, this can still yield 0 and multiple get_random_seed
invocations will open /dev/urandom multiple times and what is worse,
one can return 0 and the other some completely different number.
So either we should for the case the above is still 0 set random_seed
to some hardcoded constant other than 0 or return getpid () in that case,
or allow 0 to be returned, but arrange for the initialization to be done
at most once.

        Jakub

Reply via email to