On 15/04/2011 20:59, Eric Wong wrote: > Hello, > > I'm not very knowledgeable about OpenSSL internals, but it appears > RAND_bytes() is seeded with the pid of each process, and since pids get > recycled, it's possible for two processes sharing a common parent to get > the same random sequence over time if the common parent used the PRNG.
The prerequisite would be, surely, that: a) The common parent (or one of its ancestors) caused the PRNG to be initialised, and b) The common parent did not use the PRNG in between the offending fork()s. > This could arguably be a bug in every program using fork() + RAND_*() > and they could use pthread_atfork() to call RAND_cleanup(), but I think > OpenSSL should deal with it internally to make life easier for > application authors :) Rather than calling RAND_cleanup(), it would suffice to perturn the state, e.g., mix in something each time fork() is called - it could even be a constant - or extract some randomness. Not so sure about pthread_atfork() - that would require pthread, of course, and so is not a universal fix. > > I have a trivial test program to illustrate the issue. It's been > tested with 0.9.8e-12.el5_4.6 on CentOS and 0.9.8g-15+lenny11 and > 1.0.0d-2 on Debian. > > also downloadable here: http://yhbt.net/test_openssl_prng_fork.c > -------------------------------- 8< ------------------------------ > /* > * test program to demonstrate recycled PIDs can cause the PRNG to > * generate the same byte sequence. This should output 2 identical > * lines after running for a while. > */ > #include <sys/types.h> > #include <sys/wait.h> > #include <unistd.h> > #include <stdio.h> > #include <openssl/rand.h> > > static void dump_random(void) > { > int i; > unsigned char buf[4]; > > RAND_bytes(buf, sizeof(buf)); > printf("pid=%d ", getpid()); > for (i = 0; i < sizeof(buf); i++) > printf("\\x%02x", buf[i]); > puts(""); > } > > int main(void) > { > pid_t pid, xpid; > > /* PRNG needs to be initialized in original process to reproduce */ > RAND_bytes((unsigned char *)&pid, sizeof(pid)); > > pid = fork(); > if (pid == 0) { > dump_random(); > return 0; > } else if (pid > 0) { > wait(NULL); > > do { > xpid = fork(); > if (xpid == 0) { > if (getpid() == pid) > dump_random(); > return 0; > } else if (xpid > 0) { > wait(NULL); > } else { > perror("fork"); > } > } while (pid != xpid); > } else { > perror("fork"); > return 1; > } > > return 0; > } -- http://www.apache-ssl.org/ben.html http://www.links.org/ "There is no limit to what a man can do or how far he can go if he doesn't mind who gets the credit." - Robert Woodruff ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List [email protected] Automated List Manager [email protected]
