Bodo,

This fix seems to work fine, but there is still a (small) potential
problem...

Consider the situation where thread id 0 is valid (this is true for some
systems). If one thread (thread id N) unsets the flags and releases the lock
(ssleay_rand_bytes)

  crypto_lock_rand = 0;
  locking_thread = 0;
  CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

Another thread (thread id M) locks and starts to set the flags
(ssleay_rand_bytes)

  CRYPTO_w_lock(CRYPTO_LOCK_RAND);
  crypto_lock_rand = 1;

Finally, thread 0 does a check to see if it should lock or not...
(ssleay_rand_add)

  do_not_lock = cypto_lock_rand && (locking_thread == CRYPTO_thread_id());

it will not lock as it should, because it thinks it owns the lock, which is
actually owned by thread M... Not good!



I believe that the fix is fairly simple...

  1. When setting 'crypto_lock_rand = 1', only do so after setting
'locking_thread = CRYPTO_thread_id()'... This will guarantee that a thread
checking do_not_lock will not see crypto_lock_rand flag set until after the
true locking_thread has been set.

        // md_rand.c:355 and md_rand.c:520
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);

        crypto_lock_rand = 1;
        locking_thread = CRYPTO_thread_id();

    would be written like this...
        
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);

        locking_thread = CRYPTO_thread_id();
        crypto_lock_rand = 1;


  2. When setting 'crypto_lock_rand = 0', just leave locking_thread alone.
This just removes an unnecessary assignment (0 is a valid thread id on some
systems...).

        // md_rand.c:431 and md_rand.c:538
        crypto_lock_rand = 0;
        locking_thread = 0;
        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

    would be

        crypto_lock_rand = 0;
        CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

Travis
  

-----Original Message-----
From: Bodo Moeller [mailto:[EMAIL PROTECTED]]
Subject: Re: mt issue in md_rand.c?


On Mon, Jul 02, 2001 at 08:54:15AM -0700, Travis Vitek wrote:

> The following testcase occasionally fails on several different systems
> (quite often on hp11 with a moderate load) when a thread attempts to
release
> a mutex which it doesn't own via the locking callback. I am using
debugging
> mutexes to expose the problem; most code I've seen use fast or normal
> mutexes (the default) and never check the result of the mutex lock/unlock
> operations...

I recently found and (hopefully) fixed a bug matching this
description, but did not have multi-threaded software for actually
testing it:

  *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
     combination of a flag and a thread ID variable.
     Otherwise while one thread is in ssleay_rand_bytes (which sets the
     flag), *other* threads can enter ssleay_add_bytes without obeying
     the CRYPTO_LOCK_RAND lock (and may even illegaly release the lock
     that they do not hold after the first thread unsets add_do_not_lock).
     [Bodo Moeller]

Please try the latest 0.9.6-stable snapshot
(ftp://ftp.openssl.org/snapshot/)
and report if the problem has been solved.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to