https://github.com/python/cpython/commit/23192aba206fcba093c7a424f822f77721a7cbb8 commit: 23192aba206fcba093c7a424f822f77721a7cbb8 branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: brandtbucher <[email protected]> date: 2024-04-19T22:53:18Z summary:
[3.12] GH-115874: Fix segfault in FutureIter_dealloc (GH-118114) GH-115874: Fix segfault in FutureIter_dealloc (GH-117741) (cherry picked from commit d8f350309ded3130c43f0d2809dcb8ec13112320) Co-authored-by: Savannah Ostrowski <[email protected]> files: A Misc/NEWS.d/next/Core and Builtins/2024-04-13-18-59-25.gh-issue-115874.c3xG-E.rst M Modules/_asynciomodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-13-18-59-25.gh-issue-115874.c3xG-E.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-13-18-59-25.gh-issue-115874.c3xG-E.rst new file mode 100644 index 00000000000000..5a6fa4cedd9fe4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-13-18-59-25.gh-issue-115874.c3xG-E.rst @@ -0,0 +1 @@ +Fixed a possible segfault during garbage collection of ``_asyncio.FutureIter`` objects diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index a465090bfaaa38..05e79915ba7c28 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1590,11 +1590,25 @@ static void FutureIter_dealloc(futureiterobject *it) { PyTypeObject *tp = Py_TYPE(it); - asyncio_state *state = get_asyncio_state_by_def((PyObject *)it); + + // FutureIter is a heap type so any subclass must also be a heap type. + assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); + + PyObject *module = ((PyHeapTypeObject*)tp)->ht_module; + asyncio_state *state = NULL; + PyObject_GC_UnTrack(it); tp->tp_clear((PyObject *)it); - if (state->fi_freelist_len < FI_FREELIST_MAXLEN) { + // GH-115874: We can't use PyType_GetModuleByDef here as the type might have + // already been cleared, which is also why we must check if ht_module != NULL. + // Due to this restriction, subclasses that belong to a different module + // will not be able to use the free list. + if (module && _PyModule_GetDef(module) == &_asynciomodule) { + state = get_asyncio_state(module); + } + + if (state && state->fi_freelist_len < FI_FREELIST_MAXLEN) { state->fi_freelist_len++; it->future = (FutureObj*) state->fi_freelist; state->fi_freelist = it; _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: [email protected]
