gh-149816: Fix SNI callback callable race#150018
Conversation
|
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 |
|
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 |
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 |
|
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 |
Problem
_servername_callbackcallsPyObject_CallFunctionObjArgs(sslctx->set_sni_cb, ...)using a shared field directly (cpython/Modules/_ssl.c:5188,cpython/Modules/_ssl.c:5215) without lockingsslctxand without taking a strong local reference. Another thread can concurrently clear the field in_ssl__SSLContext_sni_callback_set_implviaPy_CLEAR(self->set_sni_cb)(cpython/Modules/_ssl.c:5304), whose macro writes NULL then decrefs/frees the old object (cpython/Include/refcount.h:483-490). A concrete UAF path is: load callable pointer in_servername_callback→ concurrentPy_CLEARfrees callable → call dereferences stale pointer in_PyObject_VectorcallTstate(cpython/Objects/call.c:823).Fix
Fix adds a critical section and saves a copy into
sni_cb.Additionally, we ensure the swap of the new callback is atomic, without allowing race conditions.
Testing
Tested on MacOS.
Before
After
Using Repro:
More info