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.

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 :)

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;
}
-- 
Eric Wong
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to