From: Brandt Bucher Date: Mon, 3 Oct 2022 23:36:52 +0000 (-0700) Subject: GH-97752: Clear the `previous` member of newly-created generator/coroutine frames... X-Git-Tag: v3.12.0a1~290 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=93fcc1f4133e177882850177c2c047d46019b812;p=thirdparty%2FPython%2Fcpython.git GH-97752: Clear the `previous` member of newly-created generator/coroutine frames (GH-97795) --- diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index fb2d9ced0633..42cc20c46766 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -206,6 +206,25 @@ class GeneratorTest(unittest.TestCase): 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 000000000000..c65635070348 --- /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 14464df0a8d5..05a8cffcb8a7 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -54,6 +54,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; }