[Boost-bugs] [Boost C++ Libraries] #8532: openssl_id_func breaks OpenSSL thread safety requirements on non-Windows platforms

Subject: [Boost-bugs] [Boost C++ Libraries] #8532: openssl_id_func breaks OpenSSL thread safety requirements on non-Windows platforms
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-05-01 15:02:17


#8532: openssl_id_func breaks OpenSSL thread safety requirements on non-Windows
platforms
-----------------------------------------------------------------+----------
 Reporter: criticalsection@… | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost 1.52.0 | Severity: Problem
 Keywords: CRYPTO_set_id_callback OpenSSL ASIO "thread safety" |
-----------------------------------------------------------------+----------
 In order to be thread safe OpenSSL requires call backs that provide:

 1) Thread level locking (e.g. mutexes)

 2) A unique id for each thread

 The Boost ASIO SSL support provides 1) but only a partial implementation
 for 2). The openssl_id_func() supplied to CRYPTO_set_id_callback uses
 GetCurrentThreadId on Windows but on other platforms uses this:

     void* id = instance()->thread_id_;

     if (id == 0)
       instance()->thread_id_ = id = &id; // Ugh.

     BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
     return reinterpret_cast<unsigned long>(id);

 The is initially based on the address of the local variable id that should
 be different in each thread but may also vary in a given thread depending
 on the call stack.

 However, the value seems to be assigned to a shared instance so that all
 threads will see the same value.

 I recently discovered that some thread safety problems on iOS were being
 caused by this code.

 I worked around this problem by calling CRYPTO_set_id_callback again after
 creating an boost::asio::ssl::context to overwrite the callback with one
 like this for non Windows platforms:

 unsigned long my_openssl_id_func()
 {
   return pthread_mach_thread_np(pthread_self() );
 }

 After this change the Boost SSL ASIO library suffered no more re-entrancy
 and locking issues.

 I suggest that a solution could incorporate some or all of the following:

 -Remove the existing non Windows implementation as it doesn't seem to meet
 the OpenSSL requirements
 -Provide a pthread based implementation in openssl_id_func when PTHREADS
 are available

 -A runtime assert/exception if a suitable implementation has not been
 provided
 -Provide more control over OpenSSL initialization to the user of Boost
 ASIO so that aspects such as this can be explicitly handled.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8532>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC