Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006032OCamlOCaml standard librarypublic2013-06-05 14:142013-06-06 13:45
Reporterfrisch 
Assigned Tofrisch 
PrioritynormalSeverityminorReproducibilityhave not tried
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0006032: Random.self_init problem under Windows
DescriptionUnder Windows, the random seed is computed from the process id and the current time. As a result, the following will (with high probability) display twice the same number:

let () =
  Random.self_init ();
  Printf.printf "%i\n%!" (Random.int 10000);
  Random.self_init ();
  Printf.printf "%i\n%!" (Random.int 10000)


The code for caml_win32_random_seed (in win32.c) suggests an improvement (using RtlGenRandom). A simpler fix for the case above could be obtained simply by using a static counter (so that the same process calling self_init twice in a row will get different seeds). I want to check that nobody is against this fix.
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0009410)
xleroy (administrator)
2013-06-05 14:28

The static counter isn't going to add any entropy, even though it would make the problem less apparent. I'd prefer to look for other sources of randomness: if not the Win32 crypto API, at least something like the TSC register of x86 processors.
 
(0009411)
xleroy (administrator)
2013-06-05 15:08

I'd be tempted to use QueryPerformanceCounter, which looks reasonably portable under Win32:

int caml_win32_random_seed (intnat data[16])
{
  FILETIME t;
  LARGE_INTEGER pc;
  GetSystemTimeAsFileTime(&t);
  QueryPerformanceCounter(&pc);
  data[0] = t.dwLowDateTime;
  data[1] = t.dwHighDateTime;
  data[2] = GetCurrentProcessId();
  data[3] = pc.LowPart;
  data[4] = pc.HighPart;
  return 5;
}
(0009412)
frisch (developer)
2013-06-05 15:45

What about using:

 http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx [^]

?

maybe with a fallback (for the unlikely case where the symbol is not found in the dll or the dll cannot be loaded) to your solution.
(0009414)
xleroy (administrator)
2013-06-05 19:58

Well, using RtlGenRandom is what the comment in win32.c suggests. However, the MSDN doc is scary: "[this function] may be altered or unavailable in subsequent versions [of Windows]". CryptGenRandom is certainly more durable, but risks pulling in all of the Win32 Crypto API.

Another suspicious point: truly cryptography-quality PRNGs block until enough entropy has been gathered. (That's the difference between /dev/random and /dev/urandom under Linux.) We don't want to risk blocking while initializing OCaml's Random library module. The MSDN docs don't say whether RtlGenRandom and CryptGenRandom can block, and how to avoid blocking.

Could you be so nice as to try the QueryPerformanceCounter-based solution I suggested? (I no longer have a working Win32 development environment.) Thanks in advance.
(0009418)
frisch (developer)
2013-06-06 09:23

> Could you be so nice as to try the QueryPerformanceCounter-based solution I suggested? (I no longer have a working Win32 development environment.) Thanks in advance.

Yes, it seems to work (tried with the 32-bit msvc port).
(0009421)
frisch (developer)
2013-06-06 13:42
edited on: 2013-06-06 13:45

Commit 13750 to trunk.

(0009422)
frisch (developer)
2013-06-06 13:45

Commit 13751 adds a non-regression test (which might fail with very low probability).

- Issue History
Date Modified Username Field Change
2013-06-05 14:14 frisch New Issue
2013-06-05 14:28 xleroy Note Added: 0009410
2013-06-05 14:28 xleroy Status new => acknowledged
2013-06-05 15:08 xleroy Note Added: 0009411
2013-06-05 15:45 frisch Note Added: 0009412
2013-06-05 19:58 xleroy Note Added: 0009414
2013-06-06 09:23 frisch Note Added: 0009418
2013-06-06 13:42 frisch Note Added: 0009421
2013-06-06 13:42 frisch Assigned To => frisch
2013-06-06 13:42 frisch Status acknowledged => assigned
2013-06-06 13:45 frisch Note Added: 0009422
2013-06-06 13:45 frisch Status assigned => resolved
2013-06-06 13:45 frisch Resolution open => fixed
2013-06-06 13:45 frisch Note Edited: 0009421 View Revisions


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker