Repository navigation
Data race in test_ssl.test_sni_callback_race #150191
Copy link
Copy link
Open
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or errortestsTests in the Lib/test dirTests in the Lib/test dir
on May 21, 2026 - marked TSan detects a data race when running test_ssl.test_sni_callback_race() on Free Threading #151277 as a duplicate of this issue
on Jun 11, 2026 Oh, I created a duplicate issue (gh-151277), I forgot to check if the issue was already reported.
- added 4 commits that reference this issue
on Jul 7, 2026 I tried running the
test_sni_callback_racetest under openssl compiled with TSAN and it exposed another internal data race in openssl:Default build — setter write vs
final_server_nameread:WARNING: ThreadSanitizer: data race (pid=36258) Write of size 8 at 0x726c00056c30 by thread T15: # toggler thread #0 ssl3_ctx_callback_ctrl ssl/s3_lib.c:4200 # ctx->ext.servername_cb = fp #1 SSL_CTX_callback_ctrl ssl/ssl_lib.c:3251 #2 _ssl__SSLContext_sni_callback_set_impl Modules/_ssl.c:5319 #4 getset_set → PyObject_SetAttr # server_ctx.sni_callback = ... Previous read of size 8 at 0x726c00056c30 by thread T12: # handshake worker #0 final_server_name ssl/statem/extensions.c:1004 # reads servername_cb #1 tls_parse_all_extensions ssl/statem/extensions.c:816 #2 tls_early_post_process_client_hello ssl/statem/statem_srvr.c:1965 #7 ossl_statem_accept → #8 SSL_do_handshake #9 _ssl__SSLSocket_do_handshake_impl Modules/_ssl.c:1099 # server.do_handshake() Location: heap block of size 1768 (SSL_CTX, allocated in SSL_CTX_new from _ssl__SSLContext_impl, Modules/_ssl.c:3509)Free-threading build — same write, different read site:
WARNING: ThreadSanitizer: data race (pid=36449) Read of size 8 at 0x726c00002c30 by thread T12: # handshake worker #0 is_tls13_capable ssl/statem/statem_lib.c:1932 # if (sctx->ext.servername_cb != NULL || s->session_ctx->ext.servername_cb != NULL) #1 ssl_version_supported ssl/statem/statem_lib.c:2011 #2 ssl_choose_server_version ssl/statem/statem_lib.c:2240 #9 SSL_do_handshake → _ssl__SSLSocket_do_handshake_impl Modules/_ssl.c:1099 Previous write of size 8 by thread T15: # toggler thread #0 ssl3_ctx_callback_ctrl ssl/s3_lib.c:4200 #2 _ssl__SSLContext_sni_callback_set_impl Modules/_ssl.c:5319 SUMMARY: data race statem_lib.c:1932 in is_tls13_capableThere is also a race in
test_thread_recv_while_main_thread_sendstest:WARNING: ThreadSanitizer: data race Write of size 4 by main thread: # sock.sendall(data) #0 ssl3_write_bytes ssl/record/rec_layer_s3.c:285 # s->rwstate = SSL_NOTHING #3 SSL_write_ex2 → #4 SSL_write_ex #5 _ssl__SSLSocket_write_impl Modules/_ssl.c:2832 Previous write of size 4 by thread T272: # background sock.recv() #0 ssl3_read_bytes ssl/record/rec_layer_s3.c:681 # s->rwstate = SSL_NOTHING #4 SSL_read_ex #5 _ssl__SSLSocket_read_impl Modules/_ssl.c:2989 Location: heap block of size 5560 (the SSL object, allocated in SSL_new from newPySSLSocket, Modules/_ssl.c:959, via context.wrap_socket) SUMMARY: data race rec_layer_s3.c:285 in ssl3_write_bytesFor now, I will create a PR to skip these two tests under TSAN so that we can re-enable the TSAN CI using #153316.
- added 3 commits that reference this issue
on Jul 8, 2026 cc @ZeroIntensity for the races in
test_thread_recv_while_main_thread_sendstestCurrently, test_sni_callback_race() and test_thread_recv_while_main_thread_sends() of test_ssl are skipped when run with a thread sanitizer.
Metadata
Metadata
Assignees
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Bug report
There is a sporadic thread sanitizer reported data race in a newly added test
For example:
Here is a summary from Claude with my edits:
On the free-threaded TSAN build,
test.test_ssl.ContextTests.test_sni_callback_racesporadically reports a data race inside OpenSSL: one thread reads an ASN.1 string viaASN1_STRING_cmp(no lock held) while another writes the same heap block viaASN1_STRING_set(holding an internalCRYPTO_THREAD_lockrwlock). The test itself does not crash.Reproducer
Reproduces within ~15 runs on a 22-core machine.
TSAN report (abridged)
The writer holds an OpenSSL-owned rwlock; the reader does not take the same lock. Both call sites enter from two Python worker threads doing concurrent SSL handshakes on the same
SSLContext.Environment
main@ c35b0f2 (3.16.0a0, free-threading debug TSAN)cc @kiri11 @encukou
Linked PRs