You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by be...@apache.org on 2003/11/03 18:50:37 UTC

cvs commit: apr/threadproc/unix proc.c

ben         2003/11/03 09:50:37

  Modified:    include  apr_random.h
               random/unix apr_random.c
               test     testrand2.c
               threadproc/unix proc.c
  Log:
  Make sure randomness is different after a fork.
  
  Revision  Changes    Path
  1.2       +13 -0     apr/include/apr_random.h
  
  Index: apr_random.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_random.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- apr_random.h	3 Nov 2003 13:25:00 -0000	1.1
  +++ apr_random.h	3 Nov 2003 17:50:37 -0000	1.2
  @@ -93,4 +93,17 @@
   apr_status_t apr_random_secure_ready(apr_random_t *r);
   apr_status_t apr_random_insecure_ready(apr_random_t *r);
   
  +/* Call this in the child after forking to mix the randomness
  +   pools. Note that its generally a bad idea to fork a process with a
  +   real PRNG in it - better to have the PRNG externally and get the
  +   randomness from there. However, if you really must do it, then you
  +   should supply all your entropy to all the PRNGs - don't worry, they
  +   won't produce the same output.
  +
  +   Note that apr_proc_fork() calls this for you, so only weird
  +   applications need ever call it themselves.
  +*/
  +struct apr_proc_t;
  +void apr_random_after_fork(struct apr_proc_t *proc);
  +
   #endif /* ndef APR_RANDOM_H */
  
  
  
  1.2       +45 -2     apr/random/unix/apr_random.c
  
  Index: apr_random.c
  ===================================================================
  RCS file: /home/cvs/apr/random/unix/apr_random.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- apr_random.c	3 Nov 2003 13:25:00 -0000	1.1
  +++ apr_random.c	3 Nov 2003 17:50:37 -0000	1.2
  @@ -58,6 +58,7 @@
   #include "apr.h"
   #include "apr_pools.h"
   #include "apr_random.h"
  +#include "apr_thread_proc.h"
   #include <assert.h>
   
   #define min(a,b) ((a) < (b) ? (a) : (b))
  @@ -99,9 +100,13 @@
   #define K_size(g) ((g)->key_hash->size)
       apr_crypto_hash_t *prng_hash;
   #define B_size(g) ((g)->prng_hash->size)
  +
       unsigned char *H;
       unsigned char *H_waiting;
   #define H_size(g) (B_size(g)+K_size(g))
  +#define H_current(g) (((g)->insecure_started && !(g)->secure_started) \
  +		      ? (g)->H_waiting : (g)->H)
  +
       unsigned char *randomness;
       apr_size_t random_bytes;
       unsigned int g_for_insecure;
  @@ -109,8 +114,12 @@
       unsigned int secure_base;
       unsigned char insecure_started:1;
       unsigned char secure_started:1;
  +
  +    apr_random_t *next;
       };
   
  +static apr_random_t *all_random;
  +
   void apr_random_init(apr_random_t *g,apr_pool_t *p,
   		     apr_crypto_hash_t *pool_hash,apr_crypto_hash_t *key_hash,
   		     apr_crypto_hash_t *prng_hash)
  @@ -145,6 +154,41 @@
       g->secure_base=0;
       g->g_for_secure=APR_RANDOM_DEFAULT_G_FOR_SECURE;
       g->secure_started=g->insecure_started=0;
  +
  +    g->next=all_random;
  +    all_random=g;
  +    }
  +
  +static void mix_pid(apr_random_t *g,unsigned char *H,pid_t pid)
  +    {
  +    hash_init(g->key_hash);
  +    hash_add(g->key_hash,H,H_size(g));
  +    hash_add(g->key_hash,&pid,sizeof pid);
  +    hash_finish(g->key_hash,H);
  +    }
  +
  +static void mixer(apr_random_t *g,pid_t pid)
  +    {
  +    unsigned char *H=H_current(g);
  +
  +    /* mix the PID into the current H */
  +    mix_pid(g,H,pid);
  +    /* if we are in waiting, then also mix into main H */
  +    if(H != g->H)
  +	mix_pid(g,g->H,pid);
  +    /* change order of pool mixing for good measure - note that going
  +       backwards is much better than going forwards */
  +    --g->generation;
  +    /* blow away any lingering randomness */
  +    g->random_bytes=0;
  +    }
  +
  +void apr_random_after_fork(apr_proc_t *proc)
  +    {
  +    apr_random_t *r;
  +
  +    for(r=all_random ; r ; r=r->next)
  +	mixer(r,proc->pid);
       }
   
   apr_random_t *apr_random_standard_new(apr_pool_t *p)
  @@ -159,8 +203,7 @@
   static void rekey(apr_random_t *g)
       {
       int n;
  -    unsigned char *H=(g->insecure_started && !g->secure_started) ? g->H_waiting
  -	: g->H;
  +    unsigned char *H=H_current(g);
   
       hash_init(g->key_hash);
       hash_add(g->key_hash,H,H_size(g));
  
  
  
  1.2       +83 -0     apr/test/testrand2.c
  
  Index: testrand2.c
  ===================================================================
  RCS file: /home/cvs/apr/test/testrand2.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- testrand2.c	3 Nov 2003 13:25:01 -0000	1.1
  +++ testrand2.c	3 Nov 2003 17:50:37 -0000	1.2
  @@ -54,6 +54,7 @@
   
   #include "apr_general.h"
   #include "apr_random.h"
  +#include "apr_thread_proc.h"
   #include <errno.h>
   #include <stdio.h>
   #include <stdlib.h>
  @@ -102,6 +103,20 @@
   	}
       }
   
  +static int rand_check_kat(rnd_fn *f,apr_random_t *r,
  +			  const unsigned char expected[128])
  +    {
  +    unsigned char c[128];
  +    apr_status_t rv;
  +
  +    rv=f(r,c,128);
  +    if(rv)
  +	return 2;
  +    if(memcmp(c,expected,128))
  +	return 1;
  +    return 0;
  +    }
  +
   static void rand_add_zeroes(apr_random_t *r)
       {
       static unsigned char c[2048];
  @@ -234,6 +249,73 @@
       rand_run_kat(tc,apr_random_secure_bytes,r,expected);
       }    
   
  +static void rand_fork(CuTest *tc)
  +    {
  +    apr_proc_t proc;
  +    apr_status_t rv;
  +    unsigned char expected[128]=
  +	{  0xac,0x93,0xd2,0x5c,0xc7,0xf5,0x8d,0xc2,
  +	   0xd8,0x8d,0xb6,0x7a,0x94,0xe1,0x83,0x4c,
  +	   0x26,0xe2,0x38,0x6d,0xf5,0xbd,0x9d,0x6e,
  +	   0x91,0x77,0x3a,0x4b,0x9b,0xef,0x9b,0xa3,
  +	   0x9f,0xf6,0x6d,0x0c,0xdc,0x4b,0x02,0xe9,
  +	   0x5d,0x3d,0xfc,0x92,0x6b,0xdf,0xc9,0xef,
  +	   0xb9,0xa8,0x74,0x09,0xa3,0xff,0x64,0x8d,
  +	   0x19,0xc1,0x31,0x31,0x17,0xe1,0xb7,0x7a,
  +	   0xe7,0x55,0x14,0x92,0x05,0xe3,0x1e,0xb8,
  +	   0x9b,0x1b,0xdc,0xac,0x0e,0x15,0x08,0xa2,
  +	   0x93,0x13,0xf6,0x04,0xc6,0x9d,0xf8,0x7f,
  +	   0x26,0x32,0x68,0x43,0x2e,0x5a,0x4f,0x47,
  +	   0xe8,0xf8,0x59,0xb7,0xfb,0xbe,0x30,0x04,
  +	   0xb6,0x63,0x6f,0x19,0xf3,0x2c,0xd4,0xeb,
  +	   0x32,0x8a,0x54,0x01,0xd0,0xaf,0x3f,0x13,
  +	   0xc1,0x7f,0x10,0x2e,0x08,0x1c,0x28,0x4b, };
  +
  +    rv=apr_proc_fork(&proc,p);
  +    if(rv == APR_INCHILD)
  +	{
  +	int n;
  +
  +	n=rand_check_kat(apr_random_secure_bytes,r,expected);
  +
  +	exit(n);
  +	}
  +    else if(rv == APR_INPARENT)
  +	{
  +	int exitcode;
  +	apr_exit_why_e why;
  +
  +	rand_run_kat(tc,apr_random_secure_bytes,r,expected);
  +	apr_proc_wait(&proc,&exitcode,&why,APR_WAIT);
  +	if(why != APR_PROC_EXIT)
  +	    {
  +	    CuFail(tc,"Child terminated abnormally");
  +	    return;
  +	    }
  +	if(exitcode == 0)
  +	    {
  +	    CuFail(tc,"Child produced our randomness");
  +	    return;
  +	    }
  +	else if(exitcode == 2)
  +	    {
  +	    CuFail(tc,"Child randomness failed");
  +	    return;
  +	    }
  +	else if(exitcode != 1)
  +	    {
  +	    CuFail(tc,"Uknown child error");
  +	    return;
  +	    }
  +	}
  +    else
  +	{
  +	CuFail(tc,"Fork failed");
  +	return;
  +	}
  +    }
  +    
  +	
   CuSuite *testrand2(void)
       {
       CuSuite *suite = CuSuiteNew("Random2");
  @@ -245,6 +327,7 @@
       SUITE_ADD_TEST(suite, rand_barrier);
       SUITE_ADD_TEST(suite, rand_kat3);
       SUITE_ADD_TEST(suite, rand_kat4);
  +    SUITE_ADD_TEST(suite, rand_fork);
   
       return suite;
       }
  
  
  
  1.68      +3 -0      apr/threadproc/unix/proc.c
  
  Index: proc.c
  ===================================================================
  RCS file: /home/cvs/apr/threadproc/unix/proc.c,v
  retrieving revision 1.67
  retrieving revision 1.68
  diff -u -r1.67 -r1.68
  --- proc.c	8 May 2003 08:51:02 -0000	1.67
  +++ proc.c	3 Nov 2003 17:50:37 -0000	1.68
  @@ -56,6 +56,7 @@
   #include "apr_strings.h"
   #include "apr_portable.h"
   #include "apr_signal.h"
  +#include "apr_random.h"
   
   APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new,
                                                 apr_pool_t *pool)
  @@ -231,6 +232,8 @@
           proc->in = NULL;
           proc->out = NULL;
           proc->err = NULL;
  +
  +	apr_random_after_fork(proc);
   
           return APR_INCHILD;
       }