[Python-checkins] bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object (GH-22953)

serhiy-storchaka webhook-mailer at python.org
Thu Oct 29 05:59:30 EDT 2020


https://github.com/python/cpython/commit/350526105fa9b131d8b941ae753378b741dabb2f
commit: 350526105fa9b131d8b941ae753378b741dabb2f
branch: master
author: Yonatan Goldschmidt <yon.goldschmidt at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2020-10-29T11:58:52+02:00
summary:

bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object (GH-22953)

func_dealloc() does not handle partially-created objects. Best not to give it any.

files:
A Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst
M Objects/funcobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst
new file mode 100644
index 0000000000000..2b16e69da73b5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst	
@@ -0,0 +1,2 @@
+Fix handling of errors during creation of ``PyFunctionObject``, which resulted
+in operations on uninitialized memory. Patch by Yonatan Goldschmidt.
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 09a188664e861..9b4302a13c10f 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -19,9 +19,23 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
             return NULL;
     }
 
+    /* __module__: If module name is in globals, use it.
+       Otherwise, use None. */
+    module = PyDict_GetItemWithError(globals, __name__);
+    if (module) {
+        Py_INCREF(module);
+    }
+    else if (PyErr_Occurred()) {
+        return NULL;
+    }
+
     op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
-    if (op == NULL)
+    if (op == NULL) {
+        Py_XDECREF(module);
         return NULL;
+    }
+    /* Note: No failures from this point on, since func_dealloc() does not
+       expect a partially-created object. */
 
     op->func_weakreflist = NULL;
     Py_INCREF(code);
@@ -34,6 +48,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
     op->func_kwdefaults = NULL; /* No keyword only defaults */
     op->func_closure = NULL;
     op->vectorcall = _PyFunction_Vectorcall;
+    op->func_module = module;
 
     consts = ((PyCodeObject *)code)->co_consts;
     if (PyTuple_Size(consts) >= 1) {
@@ -47,20 +62,8 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
     op->func_doc = doc;
 
     op->func_dict = NULL;
-    op->func_module = NULL;
     op->func_annotations = NULL;
 
-    /* __module__: If module name is in globals, use it.
-       Otherwise, use None. */
-    module = PyDict_GetItemWithError(globals, __name__);
-    if (module) {
-        Py_INCREF(module);
-        op->func_module = module;
-    }
-    else if (PyErr_Occurred()) {
-        Py_DECREF(op);
-        return NULL;
-    }
     if (qualname)
         op->func_qualname = qualname;
     else



More information about the Python-checkins mailing list