diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index e5aa7da1e0df13..353073dbfce00a 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -206,6 +206,25 @@ def __del__(self): finally: gc.set_threshold(*thresholds) + def test_ag_frame_f_back(self): + async def f(): + yield + ag = f() + self.assertIsNone(ag.ag_frame.f_back) + + def test_cr_frame_f_back(self): + async def f(): + pass + cr = f() + self.assertIsNone(cr.cr_frame.f_back) + cr.close() # Suppress RuntimeWarning. + + def test_gi_frame_f_back(self): + def f(): + yield + gi = f() + self.assertIsNone(gi.gi_frame.f_back) + class ExceptionTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-10-03-13-35-48.gh-issue-97752.0xTjJY.rst b/Misc/NEWS.d/next/Core and Builtins/2022-10-03-13-35-48.gh-issue-97752.0xTjJY.rst new file mode 100644 index 00000000000000..c656350703489e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-10-03-13-35-48.gh-issue-97752.0xTjJY.rst @@ -0,0 +1,2 @@ +Fix possible data corruption or crashes when accessing the ``f_back`` member +of newly-created generator or coroutine frames. diff --git a/Python/frame.c b/Python/frame.c index c4e93492e081af..45072da0426964 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -52,6 +52,9 @@ _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest) assert(src->stacktop >= src->f_code->co_nlocalsplus); Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src; memcpy(dest, src, size); + // Don't leave a dangling pointer to the old frame when creating generators + // and coroutines: + dest->previous = NULL; }