Skip to content

Commit c57a33d

Browse files
[3.12] gh-122695: Fix double-free when using gc.get_referents with a freed _asyncio.FutureIter (#122837) (#122859)
[3.13] gh-122695: Fix double-free when using `gc.get_referents` with a freed `_asyncio.FutureIter` (#122837) * Backport #122834 for 3.13 (cherry picked from commit e8fb088) Co-authored-by: Peter Bierma <[email protected]>
1 parent c536f59 commit c57a33d

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

Lib/test/test_asyncio/test_futures.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,14 @@ def test_future_del_segfault(self):
641641
with self.assertRaises(AttributeError):
642642
del fut._log_traceback
643643

644+
def test_future_iter_get_referents_segfault(self):
645+
# See https://github.com/python/cpython/issues/122695
646+
import _asyncio
647+
it = iter(self._new_future(loop=self.loop))
648+
del it
649+
evil = gc.get_referents(_asyncio)
650+
gc.collect()
651+
644652

645653
@unittest.skipUnless(hasattr(futures, '_CFuture'),
646654
'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 & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3606,14 +3606,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
36063606
Py_VISIT(state->iscoroutine_typecache);
36073607

36083608
Py_VISIT(state->context_kwname);
3609-
3610-
// Visit freelist.
3611-
PyObject *next = (PyObject*) state->fi_freelist;
3612-
while (next != NULL) {
3613-
PyObject *current = next;
3614-
Py_VISIT(current);
3615-
next = (PyObject*) ((futureiterobject*) current)->future;
3616-
}
36173609
return 0;
36183610
}
36193611

0 commit comments

Comments
 (0)