CVE-2008-0166 is an infamous example of using uninitialized memory for random number generation. A Debian maintainer commented out two lines of code to silence Valgrind, which complained about the uses of uninitialized memory as a ``bonus’’ source of entropy, and this change caused OpenSSL to generate bogus keys on Debian-based systems.
Actually, using uninitialized memory has always been a very bad idea, not only because it confuses developers and tools like Valgrind, but because a smart C compiler will kick you in the teeth. Here is one example in FreeBSD and Mac OS X libc.
srandomdev() function is used to seed
to its manpage, ``suitable for cryptographic use.’’ It will first
/dev/random, which is non-blocking on FreeBSD and Mac OS X;
if that fails, it falls back to using current time and pid, with
some amazing extra bits.
1 2 3 4 5
You can see that the seed is computed using results from
getpid(), mixed with the value of an uninitialized stack
junk. Here’s the corresponding assembly code from Mac
OS X 10.6 (Snow Leopard).
1 2 3 4 5 6 7 8 9 10 11
Everything looks good so far. Now let’s look at the same code from 10.7 (Lion) and 10.8 (Mountain Lion).
1 2 3 4 5
Wait, the entire seed computation is gone! The results of
getpid() are not used at all;
is called with some ``garbage’’ value.
I guess Apple has switched from GCC to LLVM for compiling libc in
newer Mac OS X. Since the C code contains undefined behavior, the
use of uninitialized variable
junk, LLVM optimizes away the
computation more aggressively. You should see the same assembly
if compiling FreeBSD using LLVM.
There are several interesting questions to explore.
Is it possible to trigger this by somehow failing
/dev/randomon FreeBSD and Mac OS X?
How random is the
srandom()seed now compiled using LLVM, which is just the value of
%edi? Looks like it’s the lower 32 bits of the address of the stack variable
Does GCC generate ``correct’’ code? Probably not. The last
%ebx, which is unlikely to correspond to the value of
junkbut the file descriptor of
In short, just don’t use uninitialized memory for more randomness.
The use of
in 1997. Google shows a bunch of similar usages and fixes.
sranddev()shares the same fall-back code.
DragonFly BSD developers added comments ``XXX left uninitialized on purpose’’ for
OpenBSD developers removed the code in 2005.