<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>
GitLab
</title>


<style>img {
max-width: 100%; height: auto;
}
</style>
</head>
<body>
<div class="content">
<div style="">
<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">WARNING: ThreadSanitizer: data race (pid=636)</span>
<span id="LC2" class="line" lang="plaintext">  Read of size 4 at 0x7b8c00012014 by thread T11:</span>
<span id="LC3" class="line" lang="plaintext">    #0 gnutls_record_send2 /home/chouquette/dev/vlc/contrib/native/gnutls/lib/record.c:1983 (libgnutls_plugin.so+0x20c52)</span>
<span id="LC4" class="line" lang="plaintext">    #1 gnutls_record_send /home/chouquette/dev/vlc/contrib/native/gnutls/lib/record.c:1944 (libgnutls_plugin.so+0x21115)</span>
<span id="LC5" class="line" lang="plaintext">    #2 gnutls_Send ../../modules/misc/gnutls.c:175 (libgnutls_plugin.so+0x197f3)</span>
<span id="LC6" class="line" lang="plaintext">    #3 vlc_https_send ../../modules/access/http/h2output.c:204 (libhttps_plugin.so+0xfddd)</span>
<span id="LC7" class="line" lang="plaintext">    #4 vlc_h2_frame_send ../../modules/access/http/h2output.c:250 (libhttps_plugin.so+0xffdc)</span>
<span id="LC8" class="line" lang="plaintext">    #5 vlc_h2_output_thread ../../modules/access/http/h2output.c:265 (libhttps_plugin.so+0x1006d)</span>
<span id="LC9" class="line" lang="plaintext">    #6 vlc_h2_client_output_thread ../../modules/access/http/h2output.c:299 (libhttps_plugin.so+0x101fb)</span>
<span id="LC10" class="line" lang="plaintext">    #7 <null> <null> (libtsan.so.0+0x29b4d)</span>
<span id="LC11" class="line" lang="plaintext"></span>
<span id="LC12" class="line" lang="plaintext">  Previous write of size 4 at 0x7b8c00012014 by thread T12:</span>
<span id="LC13" class="line" lang="plaintext">    #0 check_session_status /home/chouquette/dev/vlc/contrib/native/gnutls/lib/record.c:1690 (libgnutls_plugin.so+0x20204)</span>
<span id="LC14" class="line" lang="plaintext">    #1 _gnutls_recv_int /home/chouquette/dev/vlc/contrib/native/gnutls/lib/record.c:1753 (libgnutls_plugin.so+0x2055c)</span>
<span id="LC15" class="line" lang="plaintext">    #2 gnutls_record_recv /home/chouquette/dev/vlc/contrib/native/gnutls/lib/record.c:2261 (libgnutls_plugin.so+0x215ca)</span>
<span id="LC16" class="line" lang="plaintext">    #3 gnutls_Recv ../../modules/misc/gnutls.c:146 (libgnutls_plugin.so+0x196d0)</span>
<span id="LC17" class="line" lang="plaintext">    #4 vlc_https_recv ../../modules/access/http/h2conn.c:563 (libhttps_plugin.so+0x122c4)</span>
<span id="LC18" class="line" lang="plaintext">    #5 vlc_h2_frame_recv ../../modules/access/http/h2conn.c:606 (libhttps_plugin.so+0x12453)</span>
<span id="LC19" class="line" lang="plaintext">    #6 vlc_h2_recv_thread ../../modules/access/http/h2conn.c:656 (libhttps_plugin.so+0x1270d)</span>
<span id="LC20" class="line" lang="plaintext">    #7 <null> <null> (libtsan.so.0+0x29b4d)</span>
<span id="LC21" class="line" lang="plaintext"></span>
<span id="LC22" class="line" lang="plaintext">  Location is heap block of size 6504 at 0x7b8c00011800 allocated by thread T5:</span>
<span id="LC23" class="line" lang="plaintext">    #0 calloc <null> (libtsan.so.0+0x2b333)</span>
<span id="LC24" class="line" lang="plaintext">    #1 gnutls_init /home/chouquette/dev/vlc/contrib/native/gnutls/lib/state.c:450 (libgnutls_plugin.so+0x63a18)</span>
<span id="LC25" class="line" lang="plaintext">    #2 gnutls_SessionOpen ../../modules/misc/gnutls.c:241 (libgnutls_plugin.so+0x199fe)</span>
<span id="LC26" class="line" lang="plaintext">    #3 gnutls_ClientSessionOpen ../../modules/misc/gnutls.c:386 (libgnutls_plugin.so+0x1a22c)</span>
<span id="LC27" class="line" lang="plaintext">    #4 vlc_tls_ClientSessionCreate ../../src/network/tls.c:151 (libvlccore.so.9+0x165aac)</span>
<span id="LC28" class="line" lang="plaintext">    #5 vlc_tls_SocketOpenTLS ../../src/network/tls.c:242 (libvlccore.so.9+0x16607d)</span>
<span id="LC29" class="line" lang="plaintext">    #6 vlc_https_connect ../../modules/access/http/connmgr.c:65 (libhttps_plugin.so+0x15662)</span>
<span id="LC30" class="line" lang="plaintext">    #7 vlc_https_request ../../modules/access/http/connmgr.c:175 (libhttps_plugin.so+0x15b3d)</span>
<span id="LC31" class="line" lang="plaintext">    #8 vlc_http_mgr_request ../../modules/access/http/connmgr.c:258 (libhttps_plugin.so+0x15f2a)</span>
<span id="LC32" class="line" lang="plaintext">    #9 vlc_http_res_open ../../modules/access/http/resource.c:93 (libhttps_plugin.so+0x90c0)</span>
<span id="LC33" class="line" lang="plaintext">    #10 vlc_http_res_get_status ../../modules/access/http/resource.c:138 (libhttps_plugin.so+0x92aa)</span>
<span id="LC34" class="line" lang="plaintext">    #11 Open ../../modules/access/http/access.c:206 (libhttps_plugin.so+0x47df)</span>
<span id="LC35" class="line" lang="plaintext">    #12 generic_start ../../src/modules/modules.c:320 (libvlccore.so.9+0x8dcde)</span>
<span id="LC36" class="line" lang="plaintext">    #13 module_load ../../src/modules/modules.c:167 (libvlccore.so.9+0x8d4a0)</span>
<span id="LC37" class="line" lang="plaintext">    #14 vlc_module_load ../../src/modules/modules.c:244 (libvlccore.so.9+0x8d84f)</span>
<span id="LC38" class="line" lang="plaintext">    #15 module_need ../../src/modules/modules.c:335 (libvlccore.so.9+0x8de38)</span>
<span id="LC39" class="line" lang="plaintext">    #16 access_New ../../src/input/access.c:149 (libvlccore.so.9+0xc098e)</span>
<span id="LC40" class="line" lang="plaintext">    #17 stream_AccessNew ../../src/input/access.c:294 (libvlccore.so.9+0xc12ed)</span>
<span id="LC41" class="line" lang="plaintext">    #18 InputDemuxNew ../../src/input/input.c:2518 (libvlccore.so.9+0xfe90c)</span>
<span id="LC42" class="line" lang="plaintext">    #19 InputSourceNew ../../src/input/input.c:2659 (libvlccore.so.9+0xff26b)</span>
<span id="LC43" class="line" lang="plaintext">    #20 Init ../../src/input/input.c:1362 (libvlccore.so.9+0xf9b74)</span>
<span id="LC44" class="line" lang="plaintext">    #21 Run ../../src/input/input.c:532 (libvlccore.so.9+0xf62fe)</span>
<span id="LC45" class="line" lang="plaintext">    #22 <null> <null> (libtsan.so.0+0x29b4d)</span>
<span id="LC46" class="line" lang="plaintext"></span>
<span id="LC47" class="line" lang="plaintext">  Thread T11 (tid=649, running) created by thread T5 at:</span>
<span id="LC48" class="line" lang="plaintext">    #0 pthread_create <null> (libtsan.so.0+0x2be2b)</span>
<span id="LC49" class="line" lang="plaintext">    #1 vlc_clone_attr ../../src/posix/thread.c:421 (libvlccore.so.9+0x1a2936)</span>
<span id="LC50" class="line" lang="plaintext">    #2 vlc_clone ../../src/posix/thread.c:433 (libvlccore.so.9+0x1a29c3)</span>
<span id="LC51" class="line" lang="plaintext">    #3 vlc_h2_output_create ../../modules/access/http/h2output.c:323 (libhttps_plugin.so+0x10388)</span>
<span id="LC52" class="line" lang="plaintext">    #4 vlc_h2_conn_create ../../modules/access/http/h2conn.c:730 (libhttps_plugin.so+0x12ad3)</span>
<span id="LC53" class="line" lang="plaintext">    #5 vlc_https_request ../../modules/access/http/connmgr.c:190 (libhttps_plugin.so+0x15b88)</span>
<span id="LC54" class="line" lang="plaintext">    #6 vlc_http_mgr_request ../../modules/access/http/connmgr.c:258 (libhttps_plugin.so+0x15f2a)</span>
<span id="LC55" class="line" lang="plaintext">    #7 vlc_http_res_open ../../modules/access/http/resource.c:93 (libhttps_plugin.so+0x90c0)</span>
<span id="LC56" class="line" lang="plaintext">    #8 vlc_http_res_get_status ../../modules/access/http/resource.c:138 (libhttps_plugin.so+0x92aa)</span>
<span id="LC57" class="line" lang="plaintext">    #9 Open ../../modules/access/http/access.c:206 (libhttps_plugin.so+0x47df)</span>
<span id="LC58" class="line" lang="plaintext">    #10 generic_start ../../src/modules/modules.c:320 (libvlccore.so.9+0x8dcde)</span>
<span id="LC59" class="line" lang="plaintext">    #11 module_load ../../src/modules/modules.c:167 (libvlccore.so.9+0x8d4a0)</span>
<span id="LC60" class="line" lang="plaintext">    #12 vlc_module_load ../../src/modules/modules.c:244 (libvlccore.so.9+0x8d84f)</span>
<span id="LC61" class="line" lang="plaintext">    #13 module_need ../../src/modules/modules.c:335 (libvlccore.so.9+0x8de38)</span>
<span id="LC62" class="line" lang="plaintext">    #14 access_New ../../src/input/access.c:149 (libvlccore.so.9+0xc098e)</span>
<span id="LC63" class="line" lang="plaintext">    #15 stream_AccessNew ../../src/input/access.c:294 (libvlccore.so.9+0xc12ed)</span>
<span id="LC64" class="line" lang="plaintext">    #16 InputDemuxNew ../../src/input/input.c:2518 (libvlccore.so.9+0xfe90c)</span>
<span id="LC65" class="line" lang="plaintext">    #17 InputSourceNew ../../src/input/input.c:2659 (libvlccore.so.9+0xff26b)</span>
<span id="LC66" class="line" lang="plaintext">    #18 Init ../../src/input/input.c:1362 (libvlccore.so.9+0xf9b74)</span>
<span id="LC67" class="line" lang="plaintext">    #19 Run ../../src/input/input.c:532 (libvlccore.so.9+0xf62fe)</span>
<span id="LC68" class="line" lang="plaintext">    #20 <null> <null> (libtsan.so.0+0x29b4d)</span>
<span id="LC69" class="line" lang="plaintext"></span>
<span id="LC70" class="line" lang="plaintext">  Thread T12 (tid=650, running) created by thread T5 at:</span>
<span id="LC71" class="line" lang="plaintext">    #0 pthread_create <null> (libtsan.so.0+0x2be2b)</span>
<span id="LC72" class="line" lang="plaintext">    #1 vlc_clone_attr ../../src/posix/thread.c:421 (libvlccore.so.9+0x1a2936)</span>
<span id="LC73" class="line" lang="plaintext">    #2 vlc_clone ../../src/posix/thread.c:433 (libvlccore.so.9+0x1a29c3)</span>
<span id="LC74" class="line" lang="plaintext">    #3 vlc_h2_conn_create ../../modules/access/http/h2conn.c:742 (libhttps_plugin.so+0x12bce)</span>
<span id="LC75" class="line" lang="plaintext">    #4 vlc_https_request ../../modules/access/http/connmgr.c:190 (libhttps_plugin.so+0x15b88)</span>
<span id="LC76" class="line" lang="plaintext">    #5 vlc_http_mgr_request ../../modules/access/http/connmgr.c:258 (libhttps_plugin.so+0x15f2a)</span>
<span id="LC77" class="line" lang="plaintext">    #6 vlc_http_res_open ../../modules/access/http/resource.c:93 (libhttps_plugin.so+0x90c0)</span>
<span id="LC78" class="line" lang="plaintext">    #7 vlc_http_res_get_status ../../modules/access/http/resource.c:138 (libhttps_plugin.so+0x92aa)</span>
<span id="LC79" class="line" lang="plaintext">    #8 Open ../../modules/access/http/access.c:206 (libhttps_plugin.so+0x47df)</span>
<span id="LC80" class="line" lang="plaintext">    #9 generic_start ../../src/modules/modules.c:320 (libvlccore.so.9+0x8dcde)</span>
<span id="LC81" class="line" lang="plaintext">    #10 module_load ../../src/modules/modules.c:167 (libvlccore.so.9+0x8d4a0)</span>
<span id="LC82" class="line" lang="plaintext">    #11 vlc_module_load ../../src/modules/modules.c:244 (libvlccore.so.9+0x8d84f)</span>
<span id="LC83" class="line" lang="plaintext">    #12 module_need ../../src/modules/modules.c:335 (libvlccore.so.9+0x8de38)</span>
<span id="LC84" class="line" lang="plaintext">    #13 access_New ../../src/input/access.c:149 (libvlccore.so.9+0xc098e)</span>
<span id="LC85" class="line" lang="plaintext">    #14 stream_AccessNew ../../src/input/access.c:294 (libvlccore.so.9+0xc12ed)</span>
<span id="LC86" class="line" lang="plaintext">    #15 InputDemuxNew ../../src/input/input.c:2518 (libvlccore.so.9+0xfe90c)</span>
<span id="LC87" class="line" lang="plaintext">    #16 InputSourceNew ../../src/input/input.c:2659 (libvlccore.so.9+0xff26b)</span>
<span id="LC88" class="line" lang="plaintext">    #17 Init ../../src/input/input.c:1362 (libvlccore.so.9+0xf9b74)</span>
<span id="LC89" class="line" lang="plaintext">    #18 Run ../../src/input/input.c:532 (libvlccore.so.9+0xf62fe)</span>
<span id="LC90" class="line" lang="plaintext">    #19 <null> <null> (libtsan.so.0+0x29b4d)</span>
<span id="LC91" class="line" lang="plaintext"></span>
<span id="LC92" class="line" lang="plaintext">  Thread T5 (tid=642, running) created by thread T2 at:</span>
<span id="LC93" class="line" lang="plaintext">    #0 pthread_create <null> (libtsan.so.0+0x2be2b)</span>
<span id="LC94" class="line" lang="plaintext">    #1 vlc_clone_attr ../../src/posix/thread.c:421 (libvlccore.so.9+0x1a2936)</span>
<span id="LC95" class="line" lang="plaintext">    #2 vlc_clone ../../src/posix/thread.c:433 (libvlccore.so.9+0x1a29c3)</span>
<span id="LC96" class="line" lang="plaintext">    #3 input_Start ../../src/input/input.c:192 (libvlccore.so.9+0xf4eff)</span>
<span id="LC97" class="line" lang="plaintext">    #4 PlayItem ../../src/playlist_legacy/thread.c:242 (libvlccore.so.9+0x9bb36)</span>
<span id="LC98" class="line" lang="plaintext">    #5 Next ../../src/playlist_legacy/thread.c:482 (libvlccore.so.9+0x9cc51)</span>
<span id="LC99" class="line" lang="plaintext">    #6 Thread ../../src/playlist_legacy/thread.c:507 (libvlccore.so.9+0x9cd68)</span>
<span id="LC100" class="line" lang="plaintext">    #7 <null> <null> (libtsan.so.0+0x29b4d)</span></code></pre>
<p dir="auto">Since the lines may not be accurate when taken from our contrib build (at least they weren't, compared to my local gnutls repo), here are the read/writes incriminated in the race/bug:
read:</p>
<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">       if (unlikely(!session->internals.initial_negotiation_completed)) {</span>
<span id="LC2" class="line" lang="plaintext">               /* this is to protect buggy applications from sending unencrypted</span>
<span id="LC3" class="line" lang="plaintext">                * data. We allow sending however, if we are in false start handshake</span>
<span id="LC4" class="line" lang="plaintext">                * state. */</span>
<span id="LC5" class="line" lang="plaintext">               if (session->internals.recv_state != RECV_STATE_FALSE_START &&  // <---------------</span>
<span id="LC6" class="line" lang="plaintext">                   session->internals.recv_state != RECV_STATE_EARLY_START &&</span>
<span id="LC7" class="line" lang="plaintext">                   !(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT))</span>
<span id="LC8" class="line" lang="plaintext">                       return gnutls_assert_val(GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE);</span>
<span id="LC9" class="line" lang="plaintext">       }</span></code></pre>
<p dir="auto">Which is the code added by <a href="https://gitlab.com/gnutls/gnutls/commit/6a62ddfc416a4ec2118704f93c97fdd448d66566" data-original="https://gitlab.com/gnutls/gnutls/commit/6a62ddfc416a4ec2118704f93c97fdd448d66566" data-link="false" data-link-reference="true" data-project="179611" data-commit="6a62ddfc416a4ec2118704f93c97fdd448d66566" data-reference-type="commit" data-container="body" data-placement="bottom" title="Refuse to send data during handshake" class="gfm gfm-commit has-tooltip">6a62ddfc</a></p>
<p dir="auto">Write:
record.c</p>
<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">case RECV_STATE_FALSE_START:</span>
<span id="LC2" class="line" lang="plaintext">               /* if false start is not complete we always expect for handshake packets</span>
<span id="LC3" class="line" lang="plaintext">                * prior to anything else. */</span>
<span id="LC4" class="line" lang="plaintext">               if (session->security_parameters.entity != GNUTLS_CLIENT ||</span>
<span id="LC5" class="line" lang="plaintext">                   !(session->internals.flags & GNUTLS_ENABLE_FALSE_START))</span>
<span id="LC6" class="line" lang="plaintext">                       return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);</span>
<span id="LC7" class="line" lang="plaintext"></span>
<span id="LC8" class="line" lang="plaintext">               /* Attempt to complete handshake */</span>
<span id="LC9" class="line" lang="plaintext"></span>
<span id="LC10" class="line" lang="plaintext">              session->internals.recv_state = RECV_STATE_FALSE_START_HANDLING; // <----------------</span>
<span id="LC11" class="line" lang="plaintext">              ret = gnutls_handshake(session);</span>
<span id="LC12" class="line" lang="plaintext">              if (ret < 0) {</span>
<span id="LC13" class="line" lang="plaintext">                      /* a temp or fatal error, make sure we reset the state</span>
<span id="LC14" class="line" lang="plaintext">                       * so we can resume on temp errors */</span>
<span id="LC15" class="line" lang="plaintext">                      session->internals.recv_state = RECV_STATE_FALSE_START;</span>
<span id="LC16" class="line" lang="plaintext">                      return gnutls_assert_val(ret);</span>
<span id="LC17" class="line" lang="plaintext">              }</span></code></pre>
<p dir="auto">The 2 threads racing are our http2 stack receiver thread (<code>T11</code>), and sender thread (<code>T12</code>)</p>
<p dir="auto">If VLC's usage of the API is correct, then accesses to the session's internals must be made atomic, or we need to add some synchronization on our end if it's our job to ensure the handshake ran to completion after a fast start during recv/send</p>
<p dir="auto">But in any case, as things stand, the current code/use of the API is not thread safe.</p>
<p dir="auto">I'll happily provide a patch, but should the fix be in GnuTLS, I could use some guidance :)</p>
</div>


</div>
<div class="footer" style="margin-top: 10px;">
<p style="font-size: small; color: #777777;">

<br>
Reply to this email directly or <a href="https://gitlab.com/gnutls/gnutls/issues/713#note_144089452">view it on GitLab</a>.
<br>
You're receiving this email because of your account on gitlab.com.
If you'd like to receive fewer emails, you can
<a href="https://gitlab.com/sent_notifications/4bc0d882962e8025c7bf8dd53ce72c9a/unsubscribe">unsubscribe</a>
from this thread or
adjust your notification settings.
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":"View Issue","url":"https://gitlab.com/gnutls/gnutls/issues/713#note_144089452"}}</script>
</p>
</div>
</body>
</html>