Boost C++ Libraries: Ticket #8532: openssl_id_func breaks OpenSSL thread safety requirements on non-Windows platforms https://svn.boost.org/trac10/ticket/8532 <p> In order to be thread safe OpenSSL requires call backs that provide: </p> <p> 1) Thread level locking (e.g. mutexes) </p> <p> 2) A unique id for each thread </p> <p> 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 <a class="missing wiki">GetCurrentThreadId</a> on Windows but on other platforms uses this: </p> <blockquote> <p> void* id = instance()-&gt;thread_id_; </p> </blockquote> <blockquote> <p> if (id == 0) </p> <blockquote> <p> instance()-&gt;thread_id_ = id = &amp;id; <em> Ugh. </em></p> </blockquote> </blockquote> <blockquote> <p> BOOST_ASSERT(sizeof(unsigned long) &gt;= sizeof(void*)); return reinterpret_cast&lt;unsigned long&gt;(id); </p> </blockquote> <p> 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. </p> <p> However, the value seems to be assigned to a shared instance so that all threads will see the same value. </p> <p> I recently discovered that some thread safety problems on iOS were being caused by this code. </p> <p> 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: </p> <p> unsigned long my_openssl_id_func() { </p> <blockquote> <p> return pthread_mach_thread_np(pthread_self() ); </p> </blockquote> <p> } </p> <p> After this change the Boost SSL ASIO library suffered no more re-entrancy and locking issues. </p> <p> I suggest that a solution could incorporate some or all of the following: </p> <p> -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 </p> <p> -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. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8532 Trac 1.4.3 criticalsection@… Wed, 01 May 2013 18:48:15 GMT severity changed https://svn.boost.org/trac10/ticket/8532#comment:1 https://svn.boost.org/trac10/ticket/8532#comment:1 <ul> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Cosmetic</span> </li> </ul> <p> Sorry, on further testing I'm sure if that was the cause of the problem I was seeing. </p> <p> It might not actually have caused a lack of thread safety in OpenSSL but it doesn't really look right and probably needs updating. </p> <p> I have downgraded the severity to Cosmetic </p> Ticket chris_kohlhoff Fri, 24 May 2013 02:49:22 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/8532#comment:2 https://svn.boost.org/trac10/ticket/8532#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> The instance()-&gt;thread_id_ member is a thread-local variable. </p> <p> Please open a new ticket if you can reproduce the issue with a small, self-contained test case. Thanks. </p> Ticket anonymous Fri, 24 May 2013 09:09:44 GMT <link>https://svn.boost.org/trac10/ticket/8532#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8532#comment:3</guid> <description> <p> Sorry, I didn't notice it was thread local. As each thread has its own stack I guess the address of &amp;id is guaranteed to be local. </p> <p> Perhaps, the "Ugh." comment is misleading then. It could just say 'Take address of location on the thread's stack that will be unique per thread". </p> <p> BTW, thanks for a great library! </p> </description> <category>Ticket</category> </item> </channel> </rss>