From 57b3641afed157b27a59a5b5fcffeff7c39a52e7 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Sun, 25 Oct 2020 01:40:50 +0200 Subject: [PATCH 1/5] bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object func_dealloc() does not handle partially-created objects. Best not to give it any. --- Objects/funcobject.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 09a188664e8611..777927ea3e1e0f 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -19,9 +19,21 @@ 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) 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 +46,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 +60,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 From 44efc82fbcd1d8ac1d04717acdfb92a05c8db053 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Tue, 27 Oct 2020 23:34:19 +0200 Subject: [PATCH 2/5] Add NEWS entry --- .../Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst 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 00000000000000..7d13a61e0e948d --- /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``s, which resulted +in operations on uninitialized memory. Patch by Yonatan Goldschmidt. From 67c0bc1c58bfebecb381cc90412d7afa3039638f Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Tue, 27 Oct 2020 23:34:28 +0200 Subject: [PATCH 3/5] Add missing XDECREF --- Objects/funcobject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 777927ea3e1e0f..8dd2f6c681b772 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -30,8 +30,10 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname } 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. */ From ecf9d501ca689c09eeffafa7e3d981b3e584ea79 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Tue, 27 Oct 2020 23:35:32 +0200 Subject: [PATCH 4/5] Fix broken spacing --- Objects/funcobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 8dd2f6c681b772..9b4302a13c10f8 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -20,7 +20,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname } /* __module__: If module name is in globals, use it. - Otherwise, use None. */ + Otherwise, use None. */ module = PyDict_GetItemWithError(globals, __name__); if (module) { Py_INCREF(module); From 52c1da4ede222bf5d9f0e1adff992fcdc0f7ecb5 Mon Sep 17 00:00:00 2001 From: Yonatan Goldschmidt Date: Wed, 28 Oct 2020 00:19:22 +0200 Subject: [PATCH 5/5] Fix RST syntax --- .../Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7d13a61e0e948d..2b16e69da73b5f 100644 --- 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 @@ -1,2 +1,2 @@ -Fix handling of errors during creation of ``PyFunctionObject``s, which resulted +Fix handling of errors during creation of ``PyFunctionObject``, which resulted in operations on uninitialized memory. Patch by Yonatan Goldschmidt.