<div dir="ltr"><div>Hi,</div><div><br></div><div>We upgraded a code base from openssl 1.0.2 to openssl1.1.1b.</div><div>The upgrade was straightforward and we manage to activate and use TLS1.3.</div><div></div><div>OpenSSL is used to implement multi-threaded HTTPS server. <br></div><div><br></div><div>While using TLS1.3 as the minimum version with option SSL_OP_NO_TICKET  the app crash randomly due to a race condition in openssl, exactly when 2 threads use the same SSL_SESSION*.</div><div><br></div><div>Some t<br></div><div><br></div><div>We don't install any session management callback and we keep session caching mode to 2 ( SSL_SESS_CACHE_SERVER).</div><div><br></div><div>I made some debugging/tracing and I found that 
SSL_OP_NO_TICKET force openssl to call lookup_sess_in_cache() function ( file ssl_sess.c )  <br></div><div><br></div><div>

<div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Consolas,"Courier New",monospace;font-weight:normal;font-size:14px;line-height:19px;white-space:pre"><div><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">       CRYPTO_THREAD_read_lock</span><span style="color:rgb(212,212,212)">(s-></span><span style="color:rgb(156,220,254)">session_ctx</span><span style="color:rgb(212,212,212)">-></span><span style="color:rgb(156,220,254)">lock</span><span style="color:rgb(212,212,212)">);</span></div><div><span style="color:rgb(212,212,212)">        ret </span><span style="color:rgb(212,212,212)">=</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(220,220,170)">lh_SSL_SESSION_retrieve</span><span style="color:rgb(212,212,212)">(s-></span><span style="color:rgb(156,220,254)">session_ctx</span><span style="color:rgb(212,212,212)">-></span><span style="color:rgb(156,220,254)">sessions</span><span style="color:rgb(212,212,212)">, </span><span style="color:rgb(212,212,212)">&</span><span style="color:rgb(212,212,212)">data);</span></div><div><span style="color:rgb(212,212,212)">        </span><span style="color:rgb(197,134,192)">if</span><span style="color:rgb(212,212,212)"> (ret </span><span style="color:rgb(212,212,212)">!=</span><span style="color:rgb(212,212,212)"> </span><span style="color:rgb(86,156,214)">NULL</span><span style="color:rgb(212,212,212)">) {</span></div><div><span style="color:rgb(212,212,212)">            </span><span style="color:rgb(96,139,78)">/* don't allow other threads to steal it: */</span></div><div><span style="color:rgb(212,212,212)">            </span><span style="color:rgb(220,220,170)">SSL_SESSION_up_ref</span><span style="color:rgb(212,212,212)">(ret);</span></div><div><span style="color:rgb(212,212,212)">        }</span></div><div><span style="color:rgb(212,212,212)">        </span><span style="color:rgb(220,220,170)">CRYPTO_THREAD_unlock</span><span style="color:rgb(212,212,212)">(s-></span><span style="color:rgb(156,220,254)">session_ctx</span><span style="color:rgb(212,212,212)">-></span><span style="color:rgb(156,220,254)">lock</span><span style="color:rgb(212,212,212)">);</span></div></div>

</div><div><br></div><div>
lh_SSL_SESSION_retriev() doesn't make any lock check in retrieved session and 
lookup_sess_in_cache don't lock the session avec SSL_SESSION have a CRYPT_RWLOCK member.</div><div><br></div><div>I can't provide a sample to reproduce the crash, it's totaly random.

<div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Consolas,"Courier New",monospace;font-weight:normal;font-size:14px;line-height:19px;white-space:pre"><div><span style="color:rgb(212,212,212)"></span></div></div> <br></div><div>Here example of thread call stack:</div><div><br></div><div>Thread1:</div><div style="margin-left:40px">libssl-1_1-x64.dll!tls_parse_ctos_supported_groups(ssl_st * s, PACKET * pkt, unsigned int context, x509_st * x, unsigned __int64 chainidx) Ligne 966   C<br>    libssl-1_1-x64.dll!tls_parse_extension(ssl_st * s, tlsext_index_en idx, int context, raw_extension_st * exts, x509_st * x, unsigned __int64 chainidx) Ligne 715 C<br>    libssl-1_1-x64.dll!tls_parse_all_extensions(ssl_st * s, int context, raw_extension_st * exts, x509_st * x, unsigned __int64 chainidx, int fin) Ligne 748        C<br>    libssl-1_1-x64.dll!tls_early_post_process_client_hello(ssl_st * s) Ligne 1883   C<br>    libssl-1_1-x64.dll!tls_post_process_client_hello(ssl_st * s, WORK_STATE wst) Ligne 2222 C<br>    libssl-1_1-x64.dll!ossl_statem_server_post_process_message(ssl_st * s, WORK_STATE wst) Ligne 1220       C<br>    libssl-1_1-x64.dll!read_state_machine(ssl_st * s) Ligne 664     C<br>    libssl-1_1-x64.dll!state_machine(ssl_st * s, int server) Ligne 434      C<br>    libssl-1_1-x64.dll!ossl_statem_accept(ssl_st * s) Ligne 256     C<br>    libssl-1_1-x64.dll!ssl3_read_bytes(ssl_st * s, int type, int * recvd_type, unsigned char * buf, unsigned __int64 len, int peek, unsigned __int64 * readbytes) Ligne 1270        C<br>    libssl-1_1-x64.dll!ssl3_read_internal(ssl_st * s, void * buf, unsigned __int64 len, int peek, unsigned __int64 * readbytes) Ligne 4473  C<br>    libssl-1_1-x64.dll!ssl3_read(ssl_st * s, void * buf, unsigned __int64 len, unsigned __int64 * readbytes) Ligne 4498     C<br>    libssl-1_1-x64.dll!ssl_read_internal(ssl_st * s, void * buf, unsigned __int64 num, unsigned __int64 * readbytes) Ligne 1754     C<br>    libssl-1_1-x64.dll!SSL_read(ssl_st * s, void * buf, int num) Ligne 1766 C</div><div style="margin-left:40px"><br></div><div>Thread2:</div><div style="margin-left:40px">         libcrypto-1_1-x64.dll!CRYPTO_malloc(unsigned __int64 num, const char * file, int line) Ligne 222        C<br> libssl-1_1-x64.dll!tls1_save_u16(PACKET * pkt, wchar_t * * pdest, unsigned __int64 * pdestlen) Ligne 1779  C<br>    libssl-1_1-x64.dll!tls_parse_ctos_supported_groups(ssl_st * s, PACKET * pkt, unsigned int context, x509_st * x, unsigned __int64 chainidx) Ligne 968    C<br>    libssl-1_1-x64.dll!tls_parse_extension(ssl_st * s, tlsext_index_en idx, int context, raw_extension_st * exts, x509_st * x, unsigned __int64 chainidx) Ligne 715 C<br>    libssl-1_1-x64.dll!tls_parse_all_extensions(ssl_st * s, int context, raw_extension_st * exts, x509_st * x, unsigned __int64 chainidx, int fin) Ligne 748        C<br>    libssl-1_1-x64.dll!tls_early_post_process_client_hello(ssl_st * s) Ligne 1883   C<br>    libssl-1_1-x64.dll!tls_post_process_client_hello(ssl_st * s, WORK_STATE wst) Ligne 2222 C<br>    libssl-1_1-x64.dll!ossl_statem_server_post_process_message(ssl_st * s, WORK_STATE wst) Ligne 1220       C<br>    libssl-1_1-x64.dll!read_state_machine(ssl_st * s) Ligne 664     C<br>    libssl-1_1-x64.dll!state_machine(ssl_st * s, int server) Ligne 434      C<br>    libssl-1_1-x64.dll!ossl_statem_accept(ssl_st * s) Ligne 256     C<br>    libssl-1_1-x64.dll!ssl3_read_bytes(ssl_st * s, int type, int * recvd_type, unsigned char * buf, unsigned __int64 len, int peek, unsigned __int64 * readbytes) Ligne 1270        C<br>    libssl-1_1-x64.dll!ssl3_read_internal(ssl_st * s, void * buf, unsigned __int64 len, int peek, unsigned __int64 * readbytes) Ligne 4473  C<br>    libssl-1_1-x64.dll!ssl3_read(ssl_st * s, void * buf, unsigned __int64 len, unsigned __int64 * readbytes) Ligne 4498     C<br>    libssl-1_1-x64.dll!ssl_read_internal(ssl_st * s, void * buf, unsigned __int64 num, unsigned __int64 * readbytes) Ligne 1754     C<br>    libssl-1_1-x64.dll!SSL_read(ssl_st * s, void * buf, int num) Ligne 1766 C</div><div style="margin-left:40px"><br></div><br></div>