From 4a3fe0b72fc94590f0c75aae1c48a8ba0545e266 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 22 Oct 2026 16:55:09 +0100 Subject: [PATCH] [3.15] Fix unchecked `NULL` returns in several C modules (GH-160213) (cherry picked from commit a930e524cbe7cd3a35f27a1c33e7d684909d765a) Co-authored-by: Stan Ulbrych --- Modules/_elementtree.c | 3 +++ Modules/_io/winconsoleio.c | 4 ++++ Modules/_testinternalcapi.c | 3 +++ Modules/_xxtestfuzz/fuzzer.c | 4 ++++ Modules/getpath.c | 6 +++++- Modules/posixmodule.c | 3 ++- Modules/readline.c | 17 +++++++++++++---- Modules/socketmodule.c | 3 +++ Python/ceval.c | 16 ++++++++++++++++ Python/crossinterp.c | 5 +++++ 10 files changed, 58 insertions(+), 6 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index fa178f53e9b3ffe..349580c8c8df363 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -4210,6 +4210,9 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, if (events_to_report == Py_None) { /* default is "end" only */ target->end_event_obj = PyUnicode_FromString("end"); + if (target->end_event_obj == NULL) { + return NULL; + } Py_RETURN_NONE; } diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index e96c5bd738fe0ad..f9d661fb3071785 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -962,6 +962,10 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self) bytes_size += _buflen(self); bytes = PyBytes_FromStringAndSize(NULL, bytes_size); + if (bytes == NULL) { + PyMem_Free(buf); + return NULL; + } rn = _copyfrombuf(self, PyBytes_AS_STRING(bytes), bytes_size); if (len) { diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index c9f9f7aa1f4df1b..56a67965a5d061b 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -2581,6 +2581,9 @@ get_crossinterp_data(PyObject *self, PyObject *args, PyObject *kwargs) } else { mode = PyUnicode_AsUTF8(modeobj); + if (mode == NULL) { + return NULL; + } if (strlen(mode) == 0) { mode = "xidata"; } diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 02afb01d3731fbc..8c2d0e93cd72d44 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -325,6 +325,10 @@ static int fuzz_sre_match(const char* data, size_t size) { PyObject* pattern = compiled_patterns[idx]; PyObject* match_callable = PyObject_GetAttrString(pattern, "match"); + if (match_callable == NULL) { + Py_DECREF(to_match); + return 0; + } PyObject* matches = PyObject_CallOneArg(match_callable, to_match); diff --git a/Modules/getpath.c b/Modules/getpath.c index ada8a27be4c70ff..22fd42532511341 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -591,7 +591,11 @@ getpath_warn(PyObject *Py_UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "U", &msgobj)) { return NULL; } - fprintf(stderr, "%s\n", PyUnicode_AsUTF8(msgobj)); + const char *msg = PyUnicode_AsUTF8(msgobj); + if (msg == NULL) { + return NULL; + } + fprintf(stderr, "%s\n", msg); Py_RETURN_NONE; } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1a6d69824786560..7cddbe752ff8219 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5696,8 +5696,9 @@ os__getvolumepathname_impl(PyObject *module, path_t *path) goto exit; } result = PyUnicode_FromWideChar(mountpath, -1); - if (PyBytes_Check(path->object)) + if (result != NULL && PyBytes_Check(path->object)) { Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); + } exit: PyMem_Free(mountpath); diff --git a/Modules/readline.c b/Modules/readline.c index fe00f889b536532..8b49df37d1de3ff 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1508,10 +1508,19 @@ flex_complete(const char *text, int start, int end) done: if (state) { - Py_XDECREF(state->begidx); - Py_XDECREF(state->endidx); - state->begidx = PyLong_FromLong((long) start); - state->endidx = PyLong_FromLong((long) end); + PyObject *begidx = PyLong_FromLong((long) start); + PyObject *endidx = PyLong_FromLong((long) end); + if (begidx == NULL || endidx == NULL) { + Py_XDECREF(begidx); + Py_XDECREF(endidx); + PyErr_FormatUnraisable("Exception ignored while preparing " + "readline completion"); + rl_attempted_completion_over = 1; + PyGILState_Release(gilstate); + return NULL; + } + Py_XSETREF(state->begidx, begidx); + Py_XSETREF(state->endidx, endidx); } result = completion_matches((char *)text, *on_completion); PyGILState_Release(gilstate); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 68762414a4a0d35..5e3efbd2222b3b4 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1766,6 +1766,9 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) PyObject *vmId = PyUnicode_FromWideChar(guidStr, -1); res = RpcStringFreeW(&guidStr); assert(res == RPC_S_OK); + if (vmId == NULL) { + return 0; + } res = UuidToStringW(&a->ServiceId, &guidStr); if (res != RPC_S_OK) { diff --git a/Python/ceval.c b/Python/ceval.c index 04b61c59c72b380..ce397c120d46651 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1199,8 +1199,16 @@ dtrace_function_entry(_PyInterpreterFrame *frame) int lineno; PyCodeObject *code = _PyFrame_GetCode(frame); + PyObject *exc = PyErr_GetRaisedException(); filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); + PyErr_SetRaisedException(exc); + if (filename == NULL) { + filename = ""; + } + if (funcname == NULL) { + funcname = ""; + } lineno = PyUnstable_InterpreterFrame_GetLine(frame); PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); @@ -1214,8 +1222,16 @@ dtrace_function_return(_PyInterpreterFrame *frame) int lineno; PyCodeObject *code = _PyFrame_GetCode(frame); + PyObject *exc = PyErr_GetRaisedException(); filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); + PyErr_SetRaisedException(exc); + if (filename == NULL) { + filename = ""; + } + if (funcname == NULL) { + funcname = ""; + } lineno = PyUnstable_InterpreterFrame_GetLine(frame); PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); diff --git a/Python/crossinterp.c b/Python/crossinterp.c index ed77c1be646e275..b8dd5f11c2a44c7 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -664,6 +664,11 @@ check_missing___main___attr(PyObject *exc) } } const char *err = PyUnicode_AsUTF8(msgobj); + if (err == NULL) { + PyErr_Clear(); + Py_DECREF(msgobj); + return 0; + } // Check if it's a missing __main__ attr. int cmp = strncmp(err, "module '__main__' has no attribute '", 36);