From 0ee9619a4cba58730c45e65d22288fadbf7680de Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 3 Oct 2022 10:42:54 +0300 Subject: [PATCH] gh-97728: Argument Clinic: Fix uninitialized variable in the Py_UNICODE converter (GH-97729) It affects function os.system() on Windows and Windows-specific modules winreg, _winapi, _overlapped, and _msi. --- Lib/test/clinic.test | 12 +++---- ...2-10-02-11-59-23.gh-issue-97728.dIdlPE.rst | 3 ++ Modules/clinic/_winapi.c.h | 18 +++++----- Modules/clinic/overlapped.c.h | 6 ++-- Modules/clinic/posixmodule.c.h | 4 +-- PC/clinic/_msi.c.h | 10 +++--- PC/clinic/winreg.c.h | 34 +++++++++---------- Tools/clinic/clinic.py | 1 + 8 files changed, 46 insertions(+), 42 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2022-10-02-11-59-23.gh-issue-97728.dIdlPE.rst diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index c73a75b163f..47e3e02490c 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -1803,12 +1803,12 @@ static PyObject * test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *a; - const Py_UNICODE *b; - const Py_UNICODE *c; - const Py_UNICODE *d; + const Py_UNICODE *a = NULL; + const Py_UNICODE *b = NULL; + const Py_UNICODE *c = NULL; + const Py_UNICODE *d = NULL; Py_ssize_t d_length; - const Py_UNICODE *e; + const Py_UNICODE *e = NULL; Py_ssize_t e_length; if (!_PyArg_ParseStack(args, nargs, "O&O&O&u#Z#:test_Py_UNICODE_converter", @@ -1833,7 +1833,7 @@ test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a, const Py_UNICODE *b, const Py_UNICODE *c, const Py_UNICODE *d, Py_ssize_t d_length, const Py_UNICODE *e, Py_ssize_t e_length) -/*[clinic end generated code: output=4d426808cdbb3ea3 input=064a3b68ad7f04b0]*/ +/*[clinic end generated code: output=9f34a249b3071fdd input=064a3b68ad7f04b0]*/ /*[clinic input] diff --git a/Misc/NEWS.d/next/Windows/2022-10-02-11-59-23.gh-issue-97728.dIdlPE.rst b/Misc/NEWS.d/next/Windows/2022-10-02-11-59-23.gh-issue-97728.dIdlPE.rst new file mode 100644 index 00000000000..2a6a253a52a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-10-02-11-59-23.gh-issue-97728.dIdlPE.rst @@ -0,0 +1,3 @@ +Fix possible crashes caused by the use of uninitialized variables when pass +invalid arguments in :func:`os.system` on Windows and in Windows-specific +modules (like ``winreg``). diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 53d5cccdd7d..cc1a5881e0b 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -221,7 +221,7 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na DWORD protect; DWORD max_size_high; DWORD max_size_low; - LPCWSTR name; + LPCWSTR name = NULL; HANDLE _return_value; if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkkO&:CreateFileMapping", @@ -260,8 +260,8 @@ static PyObject * _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - LPCWSTR src_path; - LPCWSTR dst_path; + LPCWSTR src_path = NULL; + LPCWSTR dst_path = NULL; if (!_PyArg_CheckPositional("CreateJunction", nargs, 2, 2)) { goto exit; @@ -409,14 +409,14 @@ static PyObject * _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *application_name; + const Py_UNICODE *application_name = NULL; PyObject *command_line; PyObject *proc_attrs; PyObject *thread_attrs; BOOL inherit_handles; DWORD creation_flags; PyObject *env_mapping; - const Py_UNICODE *current_directory; + const Py_UNICODE *current_directory = NULL; PyObject *startup_info; if (!_PyArg_ParseStack(args, nargs, "O&OOOikOO&O:CreateProcess", @@ -760,7 +760,7 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg PyObject *return_value = NULL; DWORD desired_access; BOOL inherit_handle; - LPCWSTR name; + LPCWSTR name = NULL; HANDLE _return_value; if (!_PyArg_ParseStack(args, nargs, "kiO&:OpenFileMapping", @@ -890,9 +890,9 @@ _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, .kwtuple = KWTUPLE, }; #undef KWTUPLE - LPCWSTR locale; + LPCWSTR locale = NULL; DWORD flags; - LPCWSTR src; + LPCWSTR src = NULL; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, _PyUnicode_WideCharString_Converter, &locale, &flags, _PyUnicode_WideCharString_Converter, &src)) { @@ -1345,4 +1345,4 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=3e51e0b2ea3fea5a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=83c4a3f0e70e7775 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index cc0c74cc1d2..e8c2fe5653d 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -282,7 +282,7 @@ _overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t narg PyObject *EventAttributes; BOOL ManualReset; BOOL InitialState; - const Py_UNICODE *Name; + const Py_UNICODE *Name = NULL; if (!_PyArg_CheckPositional("CreateEvent", nargs, 4, 4)) { goto exit; @@ -1047,7 +1047,7 @@ static PyObject * _overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *Address; + const Py_UNICODE *Address = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("ConnectPipe", "argument", "str", arg); @@ -1254,4 +1254,4 @@ exit: return return_value; } -/*[clinic end generated code: output=ed7ca699b5cf6260 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e0f866222bd5873b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index a26cb826108..7fac0780468 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2399,7 +2399,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[1]; - const Py_UNICODE *command; + const Py_UNICODE *command = NULL; long _return_value; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -11367,4 +11367,4 @@ exit: #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=dc71eece3fc988a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd43d388b442c96d input=a9049054013a1b77]*/ diff --git a/PC/clinic/_msi.c.h b/PC/clinic/_msi.c.h index 1b7234aa03b..c77f0703927 100644 --- a/PC/clinic/_msi.c.h +++ b/PC/clinic/_msi.c.h @@ -201,7 +201,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int field; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("SetString", nargs, 2, 2)) { goto exit; @@ -244,7 +244,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int field; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("SetStream", nargs, 2, 2)) { goto exit; @@ -549,7 +549,7 @@ static PyObject * _msi_Database_OpenView(msiobj *self, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *sql; + const Py_UNICODE *sql = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("OpenView", "argument", "str", arg); @@ -638,7 +638,7 @@ static PyObject * _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *path; + const Py_UNICODE *path = NULL; int persist; if (!_PyArg_CheckPositional("OpenDatabase", nargs, 2, 2)) { @@ -695,4 +695,4 @@ _msi_CreateRecord(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=583505220fadb52b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7d083c61679eed83 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index dc78274e062..2834d9967a7 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -177,7 +177,7 @@ static PyObject * winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *computer_name; + const Py_UNICODE *computer_name = NULL; HKEY key; HKEY _return_value; @@ -243,7 +243,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; HKEY _return_value; if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { @@ -343,7 +343,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_WRITE; HKEY _return_value; @@ -427,7 +427,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { goto exit; @@ -520,7 +520,7 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; REGSAM access = KEY_WOW64_64KEY; int reserved = 0; @@ -587,7 +587,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { goto exit; @@ -731,7 +731,7 @@ static PyObject * winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *string; + const Py_UNICODE *string = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("ExpandEnvironmentStrings", "argument", "str", arg); @@ -830,8 +830,8 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; - const Py_UNICODE *file_name; + const Py_UNICODE *sub_key = NULL; + const Py_UNICODE *file_name = NULL; if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { goto exit; @@ -924,7 +924,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; @@ -1037,7 +1037,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; @@ -1159,7 +1159,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { goto exit; @@ -1216,7 +1216,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *name; + const Py_UNICODE *name = NULL; if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { goto exit; @@ -1278,7 +1278,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *file_name; + const Py_UNICODE *file_name = NULL; if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { goto exit; @@ -1341,7 +1341,7 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; DWORD type; PyObject *value_obj; @@ -1440,7 +1440,7 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *value_name; + const Py_UNICODE *value_name = NULL; PyObject *reserved; DWORD type; PyObject *value; @@ -1579,4 +1579,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=5dfd7dbce8ccb392 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7e817dc5edc914d3 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 805bdcb4365..30a67632870 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -3586,6 +3586,7 @@ def converter_init(self, *, accept={str}, zeroes=False): self.converter = '_PyUnicode_WideCharString_Opt_Converter' else: fail("Py_UNICODE_converter: illegal 'accept' argument " + repr(accept)) + self.c_default = "NULL" def cleanup(self): if not self.length: