diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 74a99880..4cac909d 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -60,6 +60,8 @@ static void Pidfile_Delete PARAMS(( void )); static void Fill_Version PARAMS(( void )); +static void Random_Init PARAMS(( void )); + static void Setup_FDStreams PARAMS(( int fd )); static bool NGIRCd_Init PARAMS(( bool )); @@ -262,6 +264,8 @@ main( int argc, const char *argv[] ) NGIRCd_SignalRestart = false; NGIRCd_SignalQuit = false; + Random_Init(); + /* Initialize modules, part I */ Log_Init( ! NGIRCd_NoDaemon ); Conf_Init( ); @@ -289,8 +293,6 @@ main( int argc, const char *argv[] ) exit(1); } - srandom(getpid()); - /* Create protocol and server identification. The syntax * used by ngIRCd in PASS commands and the known "extended * flags" are described in doc/Protocol.txt. */ @@ -564,6 +566,37 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid ) } /* NGIRCd_getNobodyID */ +static bool +Random_Init_Kern(const char *file) +{ + unsigned int seed; + bool ret = false; + int fd = open(file, O_RDONLY); + if (fd >= 0) { + if (read(fd, &seed, sizeof(seed)) == sizeof(seed)) + ret = true; + close(fd); + srandom(seed); + } + return ret; +} + +/** + * Initialize libc random(3) number generator + */ +static void +Random_Init(void) +{ + if (Random_Init_Kern("/dev/urandom")) + return; + if (Random_Init_Kern("/dev/random")) + return; + if (Random_Init_Kern("/dev/arandom")) + return; + srandom(random() ^ getpid() ^ time(NULL)); +} + + /** * Initialize ngIRCd daemon. * diff --git a/src/ngircd/proc.c b/src/ngircd/proc.c index aace8053..557543c2 100644 --- a/src/ngircd/proc.c +++ b/src/ngircd/proc.c @@ -50,6 +50,7 @@ GLOBAL pid_t Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout) { pid_t pid; + unsigned int seed; assert(proc != NULL); assert(pipefds != NULL); @@ -61,6 +62,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout return -1; } + seed = random(); pid = fork(); switch (pid) { case -1: @@ -71,6 +73,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout return -1; case 0: /* New child process: */ + srandom(seed ^ time(NULL) ^ getpid()); Signals_Exit(); signal(SIGTERM, Proc_GenericSignalHandler); signal(SIGALRM, Proc_GenericSignalHandler);