[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 e8fb088dba)

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
Victor Stinner 2024-08-09 16:33:24 +02:00 committed by GitHub
parent c536f59c62
commit c57a33d006
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 10 additions and 8 deletions

View file

@ -641,6 +641,14 @@ class CFutureTests(BaseFutureTests, test_utils.TestCase):
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
del fut._log_traceback del fut._log_traceback
def test_future_iter_get_referents_segfault(self):
# See https://github.com/python/cpython/issues/122695
import _asyncio
it = iter(self._new_future(loop=self.loop))
del it
evil = gc.get_referents(_asyncio)
gc.collect()
@unittest.skipUnless(hasattr(futures, '_CFuture'), @unittest.skipUnless(hasattr(futures, '_CFuture'),
'requires the C _asyncio module') 'requires the C _asyncio module')

View file

@ -0,0 +1,2 @@
Fixed double-free when using :func:`gc.get_referents` with a freed
:class:`asyncio.Future` iterator.

View file

@ -3606,14 +3606,6 @@ module_traverse(PyObject *mod, visitproc visit, void *arg)
Py_VISIT(state->iscoroutine_typecache); Py_VISIT(state->iscoroutine_typecache);
Py_VISIT(state->context_kwname); Py_VISIT(state->context_kwname);
// Visit freelist.
PyObject *next = (PyObject*) state->fi_freelist;
while (next != NULL) {
PyObject *current = next;
Py_VISIT(current);
next = (PyObject*) ((futureiterobject*) current)->future;
}
return 0; return 0;
} }