From 8703a4471df44b124cb5d31f0ca537c8ec2a4bf1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 14 Jul 2023 11:43:51 +0300 Subject: [PATCH] gh-86493: Fix possible leaks in some modules initialization Fix _ssl, _stat, _testinternalcapi, _threadmodule, cmath, math, posix, time. --- Include/internal/pycore_modsupport.h | 1 + Modules/_ssl.c | 9 +++++---- Modules/_stat.c | 23 ++++++++++++--------- Modules/_testinternalcapi.c | 9 +++++---- Modules/_threadmodule.c | 5 +++-- Modules/cmathmodule.c | 16 +++++++-------- Modules/mathmodule.c | 11 +++++----- Modules/posixmodule.c | 13 +++++------- Modules/timemodule.c | 8 +++----- Python/modsupport.c | 30 ++++++++++------------------ 10 files changed, 61 insertions(+), 64 deletions(-) diff --git a/Include/internal/pycore_modsupport.h b/Include/internal/pycore_modsupport.h index e577c6ba856b77..6e0699da1fd884 100644 --- a/Include/internal/pycore_modsupport.h +++ b/Include/internal/pycore_modsupport.h @@ -21,6 +21,7 @@ extern PyObject ** _Py_VaBuildStack( Py_ssize_t *p_nargs); extern PyObject* _PyModule_CreateInitialized(PyModuleDef*, int apiver); +PyAPI_FUNC(int) _PyModule_AddNew(PyObject *, const char *, PyObject *); #ifdef __cplusplus } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index df1496925f678e..473c4292b02894 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -26,6 +26,7 @@ #define OPENSSL_NO_DEPRECATED 1 #include "Python.h" +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_weakref.h" // _PyWeakref_GET_REF() /* Include symbols from _socket module */ @@ -6085,22 +6086,22 @@ sslmodule_init_versioninfo(PyObject *m) */ libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) + if (_PyModule_AddNew(m, "OPENSSL_VERSION_NUMBER", r) < 0) return -1; parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) + if (_PyModule_AddNew(m, "OPENSSL_VERSION_INFO", r) < 0) return -1; r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) + if (_PyModule_AddNew(m, "OPENSSL_VERSION", r) < 0) return -1; libver = OPENSSL_VERSION_NUMBER; parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r)) + if (_PyModule_AddNew(m, "_OPENSSL_API_VERSION", r) < 0) return -1; return 0; diff --git a/Modules/_stat.c b/Modules/_stat.c index 9747d848cbacb8..ac949885c8de82 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -11,7 +11,12 @@ * */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" +#include "pycore_modsupport.h" // _PyModule_AddNew() #ifdef __cplusplus extern "C" { @@ -591,17 +596,17 @@ stat_exec(PyObject *module) ADD_INT_MACRO(module, FILE_ATTRIBUTE_TEMPORARY); ADD_INT_MACRO(module, FILE_ATTRIBUTE_VIRTUAL); - if (PyModule_AddObject(module, "IO_REPARSE_TAG_SYMLINK", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) { - return -1; + if (_PyModule_AddNew(module, "IO_REPARSE_TAG_SYMLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) { + return -1; } - if (PyModule_AddObject(module, "IO_REPARSE_TAG_MOUNT_POINT", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) { - return -1; + if (_PyModule_AddNew(module, "IO_REPARSE_TAG_MOUNT_POINT", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) { + return -1; } - if (PyModule_AddObject(module, "IO_REPARSE_TAG_APPEXECLINK", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) { - return -1; + if (_PyModule_AddNew(module, "IO_REPARSE_TAG_APPEXECLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) { + return -1; } #endif diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 7745dd5abc22f0..99ed9b80650e00 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -23,6 +23,7 @@ #include "pycore_hashtable.h" // _Py_hashtable_new() #include "pycore_initconfig.h" // _Py_GetConfigsAsDict() #include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -1493,13 +1494,13 @@ static PyMethodDef module_functions[] = { static int module_exec(PyObject *module) { - if (PyModule_AddObject(module, "SIZEOF_PYGC_HEAD", - PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { + if (_PyModule_AddNew(module, "SIZEOF_PYGC_HEAD", + PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { return 1; } - if (PyModule_AddObject(module, "SIZEOF_TIME_T", - PyLong_FromSsize_t(sizeof(time_t))) < 0) { + if (_PyModule_AddNew(module, "SIZEOF_TIME_T", + PyLong_FromSsize_t(sizeof(time_t))) < 0) { return 1; } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 82393309b67039..92a3f1609d92a0 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_interp.h" // _PyInterpreterState.threads.count +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pylifecycle.h" #include "pycore_pystate.h" // _PyThreadState_SetCurrent() @@ -1671,8 +1672,8 @@ thread_module_exec(PyObject *module) // Round towards minus infinity timeout_max = floor(timeout_max); - if (PyModule_AddObject(module, "TIMEOUT_MAX", - PyFloat_FromDouble(timeout_max)) < 0) { + if (_PyModule_AddNew(module, "TIMEOUT_MAX", + PyFloat_FromDouble(timeout_max)) < 0) { return -1; } diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index db8b321e72e8ce..cf120206e017fa 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -8,6 +8,7 @@ #include "Python.h" #include "pycore_complexobject.h" // _Py_c_neg() +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ @@ -1217,30 +1218,29 @@ static PyMethodDef cmath_methods[] = { static int cmath_exec(PyObject *mod) { - if (PyModule_AddObject(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + if (_PyModule_AddNew(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { return -1; } - if (PyModule_AddObject(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + if (_PyModule_AddNew(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { return -1; } // 2pi - if (PyModule_AddObject(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + if (_PyModule_AddNew(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { return -1; } - if (PyModule_AddObject(mod, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { + if (_PyModule_AddNew(mod, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { return -1; } Py_complex infj = {0.0, Py_INFINITY}; - if (PyModule_AddObject(mod, "infj", - PyComplex_FromCComplex(infj)) < 0) { + if (_PyModule_AddNew(mod, "infj", PyComplex_FromCComplex(infj)) < 0) { return -1; } - if (PyModule_AddObject(mod, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { + if (_PyModule_AddNew(mod, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { return -1; } Py_complex nanj = {0.0, fabs(Py_NAN)}; - if (PyModule_AddObject(mod, "nanj", PyComplex_FromCComplex(nanj)) < 0) { + if (_PyModule_AddNew(mod, "nanj", PyComplex_FromCComplex(nanj)) < 0) { return -1; } diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index f5679fe3a6f362..404b0243f8a006 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -60,6 +60,7 @@ raised for division by zero and mod by zero. #include "pycore_bitutils.h" // _Py_bit_length() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_LookupSpecial() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR @@ -4037,20 +4038,20 @@ math_exec(PyObject *module) if (state->str___trunc__ == NULL) { return -1; } - if (PyModule_AddObject(module, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + if (_PyModule_AddNew(module, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { return -1; } - if (PyModule_AddObject(module, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + if (_PyModule_AddNew(module, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { return -1; } // 2pi - if (PyModule_AddObject(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + if (_PyModule_AddNew(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { return -1; } - if (PyModule_AddObject(module, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { + if (_PyModule_AddNew(module, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { return -1; } - if (PyModule_AddObject(module, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { + if (_PyModule_AddNew(module, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { return -1; } return 0; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index aef802c232c6ce..4a87e7d8856a83 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -17,6 +17,7 @@ #include "pycore_fileutils.h" // _Py_closerange() #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_LookupSpecial() #include "pycore_pylifecycle.h" // _PyOS_URandom() @@ -13466,7 +13467,7 @@ setup_confname_table(struct constdef *table, size_t tablesize, } Py_DECREF(o); } - return PyModule_AddObject(module, tablename, d); + return _PyModule_AddNew(module, tablename, d); } /* Return -1 on failure, 0 on success. */ @@ -16781,11 +16782,9 @@ posixmodule_exec(PyObject *m) #endif /* Initialize environ dictionary */ - PyObject *v = convertenviron(); - Py_XINCREF(v); - if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) + if (_PyModule_AddNew(m, "environ", convertenviron()) != 0) { return -1; - Py_DECREF(v); + } if (all_ins(m)) return -1; @@ -16915,9 +16914,7 @@ posixmodule_exec(PyObject *m) Py_DECREF(unicode); } - PyModule_AddObject(m, "_have_functions", list); - - return 0; + return _PyModule_AddNew(m, "_have_functions", list); } diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 3607855dbd8f27..f068fff2c33034 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH +#include "pycore_modsupport.h" // _PyModule_AddNew() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_namespace.h" // _PyNamespace_New() #include "pycore_runtime.h" // _Py_ID() @@ -1790,11 +1791,9 @@ init_timezone(PyObject *m) return -1; } #endif // MS_WINDOWS - PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); - if (tzname_obj == NULL) { + if (_PyModule_AddNew(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)) < 0) { return -1; } - PyModule_AddObject(m, "tzname", tzname_obj); #else // !HAVE_DECL_TZNAME static const time_t YEAR = (365 * 24 + 6) * 3600; time_t t; @@ -1837,10 +1836,9 @@ init_timezone(PyObject *m) PyModule_AddIntConstant(m, "daylight", janzone != julyzone); tzname_obj = Py_BuildValue("(zz)", janname, julyname); } - if (tzname_obj == NULL) { + if (_PyModule_AddNew(m, "tzname", tzname_obj) < 0) { return -1; } - PyModule_AddObject(m, "tzname", tzname_obj); #endif // !HAVE_DECL_TZNAME if (PyErr_Occurred()) { diff --git a/Python/modsupport.c b/Python/modsupport.c index 3db95f1f07284b..f89d88ef33019e 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_modsupport.h" #include "pycore_object.h" // _PyType_IsReady() typedef double va_double; @@ -606,13 +607,16 @@ PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value) PyModule_GetName(mod)); return -1; } - - if (PyDict_SetItemString(dict, name, value)) { - return -1; - } - return 0; + return PyDict_SetItemString(dict, name, value); } +int +_PyModule_AddNew(PyObject *mod, const char *name, PyObject *value) +{ + int res = PyModule_AddObjectRef(mod, name, value); + Py_XDECREF(value); + return res; +} int PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) @@ -627,25 +631,13 @@ PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - PyObject *obj = PyLong_FromLong(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; + return _PyModule_AddNew(m, name, PyLong_FromLong(value)); } int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - PyObject *obj = PyUnicode_FromString(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; + return _PyModule_AddNew(m, name, PyUnicode_FromString(value)); } int