Skip to content

Commit e8fb088

Browse files
[3.13] gh-122695: Fix double-free when using gc.get_referents with a freed _asyncio.FutureIter (#122837)
* Backport #122834 for 3.13
1 parent 60c44ed commit e8fb088

File tree

3 files changed

+10
-11
lines changed

3 files changed

+10
-11
lines changed

Lib/test/test_asyncio/test_futures.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,14 @@ def test_future_del_segfault(self):
675675
with self.assertRaises(AttributeError):
676676
del fut._log_traceback
677677

678+
def test_future_iter_get_referents_segfault(self):
679+
# See https://github.com/python/cpython/issues/122695
680+
import _asyncio
681+
it = iter(self._new_future(loop=self.loop))
682+
del it
683+
evil = gc.get_referents(_asyncio)
684+
gc.collect()
685+
678686

679687
@unittest.skipUnless(hasattr(futures, '_CFuture'),
680688
'requires the C _asyncio module')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed double-free when using :func:`gc.get_referents` with a freed
2+
:class:`asyncio.Future` iterator.

Modules/_asynciomodule.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3529,17 +3529,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
35293529
Py_VISIT(state->iscoroutine_typecache);
35303530

35313531
Py_VISIT(state->context_kwname);
3532-
3533-
#ifndef Py_GIL_DISABLED
3534-
// Visit freelist.
3535-
PyObject *next = (PyObject*) state->fi_freelist;
3536-
while (next != NULL) {
3537-
PyObject *current = next;
3538-
Py_VISIT(current);
3539-
next = (PyObject*) ((futureiterobject*) current)->future;
3540-
}
3541-
#endif
3542-
35433532
return 0;
35443533
}
35453534

0 commit comments

Comments
 (0)