summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Skeleton (bot) <31488909+miss-islington@users.noreply.github.com>2020-10-29 11:02:50 (GMT)
committerGitHub <noreply@github.com>2020-10-29 11:02:50 (GMT)
commit60324d26b58c89d68abb23fb42f1563d395c3910 (patch)
treeed2c9384c27821aae8ca39e5bfad84c5d543c65d
parent577d7c4e628260eb7926d043ca9c355ece583eb7 (diff)
downloadcpython-60324d26b58c89d68abb23fb42f1563d395c3910.zip
cpython-60324d26b58c89d68abb23fb42f1563d395c3910.tar.gz
cpython-60324d26b58c89d68abb23fb42f1563d395c3910.tar.bz2
bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object (GH-22953) (GH-23021)
func_dealloc() does not handle partially-created objects. Best not to give it any. (cherry picked from commit 350526105fa9b131d8b941ae753378b741dabb2f) Co-authored-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-10-27-21-34-05.bpo-42143.N6KXUO.rst2
-rw-r--r--Objects/funcobject.c29
2 files changed, 18 insertions, 13 deletions
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 0000000..2b16e69
--- /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 bd24f67..2c60275 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -20,9 +20,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);
@@ -35,6 +49,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) {
@@ -48,20 +63,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