bin/51205: openssl in base system is not compiled thread safe

Jim Westfall jwestfall at surrealistic.net
Mon Apr 21 00:40:20 PDT 2003


>Number:         51205
>Category:       bin
>Synopsis:       openssl in base system is not compiled thread safe
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 21 00:40:18 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Jim Westfall
>Release:        FreeBSD 4.6.2-RELEASE-p13 i386
>Organization:
n/a
>Environment:
System: FreeBSD snapper.surrealistic.net 4.6.2-RELEASE-p13 FreeBSD 4.6.2-RELEASE-p13 #10: Sat Mar 29 13:46:35 PST 2003 root at snapper.surrealistic.net:/usr/obj/usr/src/sys/SMP_46 i386
FreeBSD ultrax.surrealistic.net 4.8-RELEASE FreeBSD 4.8-RELEASE #2: Mon Apr  7 16:01:24 PDT 2003 root at ultrax.surrealistic.net:/usr/obj/usr/src/sys/UP_48  i386

>Description:
openssl thats included in the base system is not being compiled with the necessary CFLAGS to make 
it thread safe.  Because of this its possible to cause an assertion failure within libcrypto if multiple threads 
are accessing RAND_add() function call at the same time.  RAND_add() is called by both SSL_connect() and 
SSL_accept() functions.  So if multiple threads are calling either of these function it can trigger the 
assertion.  I can easily reproduce the assertion with an threaded ftp client i have been working on.  It can 
also be tiggerred with a small mod to mttest.c, which is the thread test program thats include in the openssl 
sources.
>How-To-Repeat:
it can be a bit tricky to reproduce the error, but the following patch applied to mttest.c adds
a RAND_add() call to stress the function in hopes of causing the assertion.  mttest.c is located at
/usr/src/crypto/openssl/crypto/threads/mttest.c

--- mttest.old.c        Sun Apr 20 22:36:45 2003
+++ mttest.c    Mon Apr 21 00:07:02 2003
@@ -354,6 +354,7 @@
        ctx[0]=(char *)ssl_ctx[0];
        ctx[1]=(char *)ssl_ctx[1];
 
+       usleep(1000);
        if (reconnect)
                {
                ctx[2]=(char *)SSL_new(ssl_ctx[0]);
@@ -379,7 +380,7 @@
                        {
                        fprintf(stdout,"error[%d] %lu - %d\n",
                                i,CRYPTO_thread_id(),ret);
-                       return(ret);
+                       //return(ret);
                        }
                }
        fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
@@ -407,6 +408,7 @@
        int done=0;
        int c_write,s_write;
        int do_server=0,do_client=0;
+       time_t Time = time(NULL);
 
        s_ctx=(SSL_CTX *)ctx[0];
        c_ctx=(SSL_CTX *)ctx[1];
@@ -448,6 +450,7 @@
        /* We can always do writes */
        for (;;)
                {
+               RAND_add(&Time, sizeof(Time), 0);
                do_server=0;
                do_client=0;
 

[root at ultrax]# patch -p0 < mttest.patch 
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- mttest.old.c       Sun Apr 20 22:36:45 2003
|+++ mttest.c   Mon Apr 21 00:07:02 2003
--------------------------
Patching file mttest.c using Plan A...
Hunk #1 succeeded at 354.
Hunk #2 succeeded at 380.
Hunk #3 succeeded at 408.
Hunk #4 succeeded at 450.
done
[root at ultrax]# gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -pthread
[root at ultrax]# ./mttest -CAfile /etc/ssl/certs/ftpd.pem -threads 100 -loops 100 -client_auth -ssl3 2>&1 | grep -vi error | grep -v started
client authentication 
assertion "md_c[1] == md_count[1]" failed: file "/usr/src/secure/lib/libcrypto/../../../crypto/openssl/crypto/rand/md_rand.c", line 312

this is the particular assertion in md_rand.c (0.9.7a)

#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
        assert(md_c[1] == md_count[1]);
#endif

>Fix:

I believe its just an oversite.  based on /usr/src/secure/lib/libcrypto/opensslconf-i386.h which is 
auto-generated, it shows that openssl has been configured to have thread support.  It just that the necessary 
CFLAGS where not updated in src/secure/lib/libcrypto/Makefile.inc.  It appears its been like this for a while as 
my 4.6.2 machine is effected too.  I havent looked at 5.0 is see if it is as well.

The fix depends on which openssl version is installed.

if 0.9.7x
-DOPENSSL_THREADS -pthread -D_REENTRANT -D_THREAD_SAFE -D_THREADSAFE

if 0.9.6x
-DTHREADS -pthread -D_REENTRANT -D_THREAD_SAFE -D_THREADSAFE
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list