[Python-checkins] GH-97752: Clear the `previous` member of newly-created generator/coroutine frames (GH-97795)

markshannon webhook-mailer at python.org
Mon Oct 3 19:37:00 EDT 2022


https://github.com/python/cpython/commit/93fcc1f4133e177882850177c2c047d46019b812
commit: 93fcc1f4133e177882850177c2c047d46019b812
branch: main
author: Brandt Bucher <brandtbucher at microsoft.com>
committer: markshannon <mark at hotpy.org>
date: 2022-10-04T00:36:52+01:00
summary:

GH-97752: Clear the `previous` member of newly-created generator/coroutine frames (GH-97795)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-10-03-13-35-48.gh-issue-97752.0xTjJY.rst
M Lib/test/test_generators.py
M Python/frame.c

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 @@ 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 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;
 }
 
 



More information about the Python-checkins mailing list