Skip to content

Commit 23192ab

Browse files
[3.12] GH-115874: Fix segfault in FutureIter_dealloc (GH-118114)
GH-115874: Fix segfault in FutureIter_dealloc (GH-117741) (cherry picked from commit d8f3503) Co-authored-by: Savannah Ostrowski <[email protected]>
1 parent ecb8e2b commit 23192ab

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a possible segfault during garbage collection of ``_asyncio.FutureIter`` objects

Modules/_asynciomodule.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,11 +1590,25 @@ static void
15901590
FutureIter_dealloc(futureiterobject *it)
15911591
{
15921592
PyTypeObject *tp = Py_TYPE(it);
1593-
asyncio_state *state = get_asyncio_state_by_def((PyObject *)it);
1593+
1594+
// FutureIter is a heap type so any subclass must also be a heap type.
1595+
assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE));
1596+
1597+
PyObject *module = ((PyHeapTypeObject*)tp)->ht_module;
1598+
asyncio_state *state = NULL;
1599+
15941600
PyObject_GC_UnTrack(it);
15951601
tp->tp_clear((PyObject *)it);
15961602

1597-
if (state->fi_freelist_len < FI_FREELIST_MAXLEN) {
1603+
// GH-115874: We can't use PyType_GetModuleByDef here as the type might have
1604+
// already been cleared, which is also why we must check if ht_module != NULL.
1605+
// Due to this restriction, subclasses that belong to a different module
1606+
// will not be able to use the free list.
1607+
if (module && _PyModule_GetDef(module) == &_asynciomodule) {
1608+
state = get_asyncio_state(module);
1609+
}
1610+
1611+
if (state && state->fi_freelist_len < FI_FREELIST_MAXLEN) {
15981612
state->fi_freelist_len++;
15991613
it->future = (FutureObj*) state->fi_freelist;
16001614
state->fi_freelist = it;

0 commit comments

Comments
 (0)