Subject: Re: Thread safety

Re: Thread safety

From: Eino Tuominen <eino_at_utu.fi>
Date: Wed, 02 Apr 2008 18:08:29 +0300

Eino Tuominen wrote:
> Daniel Stenberg wrote:
>>
>> The Linux man page suggests using rand_r() or even better drand48_r()
>> instead. What's the best alternative on Solaris 9?
>
> At least rand_r() and drand48() are "MT-Level = Safe" on Solaris 9. I
> think rand_r() would be the most portable, though it's far from
> cryptographically safe. But if rand() was safe enough for the use, then
> rand_r() should be okay, too.

Now that I had time to look at the actual code segment, I have a few
questions. If WIN32 is not #defined, the code looks like this:

static void randomize_key(unsigned char* key,int key_data_len)
{
   int randomized = 0;
   int counter=0;

#ifdef RANDOM_FILE
   char buffer[256];
   FILE *f = fopen(RANDOM_FILE, "rb");
   if(f) {
     size_t i;
     size_t rc = fread(buffer, key_data_len, 1, f);
     for(i=0; i<rc && counter < key_data_len; i++)
       key[counter++]=buffer[i];
     fclose(f);
   }
#endif

   if ( !randomized ) {
     for (;counter<key_data_len;counter++)
       key[counter]=(unsigned char)(rand() % 256);
   }
}

That code seems a bit weird.

man fread() says that fread() returns the number of objects read. The
prototype is

size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);

which means that in this case fread() returns 1 if read is successful (1
element of key_data_len bytes long). So only first byte gets copied in
the for() loop, and all the remaining bytes will be set by rand() in the
next loop.

How about something like this?

#ifdef RANDOM_FILE
FILE *f = fopen(RANDOM_FILE, "rb");

if (NULL != f) {
        counter = fread(key, 1, key_data_len, f);
        fclose(f);
}
#endif

(And I'd like to add assert(key_data_len <= 256) in the beginning)

How often this function is called? Is it run only in ares_init()? If so,
it could be better to use /dev/random, or what do you think?

-- 
   Eino Tuominen
Received on 2008-04-02