Bug 14561 - srand() initializes seed for random() function
Summary: srand() initializes seed for random() function
Status: ASSIGNED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.12
: P2 normal
Target Milestone: ---
Assignee: Ondrej Bilka
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-09-07 23:06 UTC by JM
Modified: 2014-06-17 04:41 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
split random seeds (1.34 KB, patch)
2012-12-19 20:40 UTC, Ondrej Bilka
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description JM 2012-09-07 23:06:29 UTC
DESCRIPTION: This problem arises if you mix the use of this two ways of generating random number: the srand()/rand() way and the srandom()/random() function family. The issue is that srand() is somehow initializing the seed for random() function, but it should be initialized *only* with srandom(). The expected behavior is random() generator not modifying its seed until done by srandom(), the current behavior is srand() changing that seed.

IMPACT: As happened to me with a scientific code, it could imply a portability problem as this is working properly (from my humble point of view) in other implementations of the library (I tested the different behavior between GNU glibc 2.12 packaged in a Scientific Linux and the BSD/MacOS-Darwin one). I detected also the problem in GNU implementation of cstdlib with C++.

HOW TO REPRODUCE: It's very easy, this is a test program:

---- START CODE ----
// Test random()
#include <stdio.h>
#include <stdlib.h>

int main() {

  int i;

  srand((unsigned)time(NULL));

  for (i=1;i<11;i++) {
	printf("%g \n",(random() / (double)0x7fffffff));
  }
}
---- CODE END ----

This is what you get with glibc-headers-2.12-1.80:

$ ./rndtest 
0.0940072
0.269949
0.729428
0.48224
0.0592921
0.4699
0.132521
0.973561
0.532405
0.167931
$ ./rndtest 
0.954241
0.686682
0.0374202
0.304717
0.497409
0.197191
0.496588
0.273147
0.345674
0.756533

This is the expected (what you get in the mentioned other implementation of stdlib.c and cstdlib):

> ./rndtest 
0.840188 
0.394383 
0.783099 
0.79844 
0.911647 
0.197551 
0.335223 
0.76823 
0.277775 
0.55397 
> ./rndtest
0.840188 
0.394383 
0.783099 
0.79844 
0.911647 
0.197551 
0.335223 
0.76823 
0.277775 
0.55397 

Many thanks.
Comment 1 Ondrej Bilka 2012-12-19 20:40:27 UTC
Created attachment 6784 [details]
split random seeds
Comment 2 Roland McGrath 2013-06-03 22:49:08 UTC
Originally the existing behavior was correct (srand/rand are just aliases for srandom/random).  Later versions of 1003.1 started specifying srandom as well as srand, so this has become nonconforming.
                                                                               
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rand.html             
                                                                                
    The implementation shall behave as if no function defined in this           
    volume of POSIX.1-2008 calls rand() or srand().                             
                                                                                
Note that srandom and random are defined in this volume:                        
                                                                                
http://pubs.opengroup.org/onlinepubs/9699919799/functions/random.html
Comment 3 Florian Weimer 2014-06-17 04:41:07 UTC
Not marking as security because these random number generators should not be used for anything security-related.