gh-149816: Fix SNI callback callable race#150018
Conversation
Sorry, something went wrong.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Sorry, something went wrong.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Sorry, something went wrong.
In Modules/_ssl.c
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Sorry, something went wrong.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Sorry, something went wrong.
8b31d08
into
python:main
May 19, 2026
|
Sorry, @kiri11 and @encukou, I could not cleanly backport this to |
Sorry, something went wrong.
Problem
Fix a use-after-free race in the SSL SNI callback on free-threaded builds. When
sni_callbackis replaced or cleared on one thread while another thread is mid-handshake, the old callback object could be freed before the handshake thread finishes calling it._servername_callback): acquiresslctx's critical section, snapshot the callback withPy_XNewRefinto a local, then release. The local strong reference keeps the callable alive for the duration of the call.sni_callback_set): already holds the same critical section via@critical_sectionclinic annotation. UsesPy_XSETREFto swap the pointer and decref the old callback atomically. The OpenSSL callback registration is set after the pointer is stored, so a concurrent handshake always finds a valid callable.sni_callback = None): unregisters the OpenSSL callback first, then clears the Python reference. Serialized against the reader by the same critical section.Testing
Adds a free-threading stress test that spawns handshake workers and a callback-toggling thread concurrently.
Plus manually tested on MacOS.
Before
After
Using Repro:
More info