DeSubstantiisSeparatis
DeSubstantiisSeparatis

Reputation: 110

Multithreaded program using OpenSSL and locks randomly crashes

I have logic for signing soap documents which use OpenSSL methods like:

OpenSSL_add_all_digests, 
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();
EVP_DigestUpdate

and so on. Of course every logic for signing document is running in different thread.

According to many topics about that subject I created static class for handling OpenSSL threads:

unsigned long SomeStaticClass::pthreads_thread_id(){
        unsigned long ret;

        ret = ( unsigned long )pthread_self();
        return ret;
}

void SomeStaticClass::pthreads_locking_callback( int mode, int type, const char* /*file*/, int /*line*/ ){

        if( mode & CRYPTO_LOCK ){
                printf("CRYPTO_LOCK_MODE type: %d\n", type);
                pthread_mutex_lock( &( lock_cs[type] ) );
        }
        else{
                printf("UNLOCK type: %d\n", type);
                pthread_mutex_unlock( &( lock_cs[type] ) );
        }
}

void SomeStaticClass::thread_setup(){

        printf("THREAD SETUP\n");
        lock_cs = ( pthread_mutex_t* )OPENSSL_malloc( CRYPTO_num_locks() * sizeof( pthread_mutex_t ) );
        for( int i = 0; i < CRYPTO_num_locks(); i++ ){
                pthread_mutex_init( &( lock_cs[i] ), NULL );
        }

        CRYPTO_set_id_callback( SomeStaticClass::pthreads_thread_id );
        CRYPTO_set_locking_callback( SomeStaticClass::pthreads_locking_callback );
}

void SomeStaticClass::thread_cleanup(){

        printf("THREAD CLEANUP\n");
        CRYPTO_set_id_callback( NULL );
        CRYPTO_set_locking_callback( NULL );
        for( int i = 0; i < CRYPTO_num_locks(); i++ ) {
                pthread_mutex_destroy( &( lock_cs[i] ) );
        }

        OPENSSL_free( lock_cs );
}

I left printf for debugging purpose. I know some of these methods are deprecated, but I can only use openssl 0.9.8.

I run thread_setup before runnig threads, and thread_cleanup after join them. Unfortunately my app still randomly crashes when I am using many threads. I get SIGSEGV just after pthreads_locking_callback was calling, cause I get on console CRYPTO_LOCK_MODE type: 2. According to backtrace it crashes after calling OpenSSL_add_all_digests or EVP_DigestUpdate.

So the question is why OpenSSL crashes since I am using proper methods for handling multi-threaded program. What I am missing?

EDIT: It is not duplicate of Tutorial on Using OpenSsl with pthreads because as I mentioned I am already using this classic functions for multithread application.

EDIT2: It works! Looks like @Matt Caswell was right. Thank you for the correct answer.

Upvotes: 2

Views: 5151

Answers (1)

Matt Caswell
Matt Caswell

Reputation: 9382

All of these functions:

SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();

Are library initialisation functions. You are expected to call them once prior to the calling of other OpenSSL functions. These are not thread safe. Call them before you setup your locking callbacks.

Upvotes: 4

Related Questions