From 8c163bbf370f6f6cedd2c07f7d54c9b36c97d8f2 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 8 Mar 2018 08:26:43 -0800 Subject: [PATCH] bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (GH-6010) (cherry picked from commit 3b20d3454e8082e07dba93617793de5dc9237828) Co-authored-by: Alexey Izbyshev --- .../2018-03-07-01-33-33.bpo-33016.Z_Med0.rst | 1 + Modules/posixmodule.c | 76 ++++++++----------- 2 files changed, 34 insertions(+), 43 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst diff --git a/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst b/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst new file mode 100644 index 00000000000..f4f78d489bf --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst @@ -0,0 +1 @@ +Fix potential use of uninitialized memory in nt._getfinalpathname diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 6bf8c6ba7b7..e8964ce3390 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -303,12 +303,6 @@ extern int lstat(const char *, struct stat *); #ifdef HAVE_PROCESS_H #include #endif -#ifndef VOLUME_NAME_DOS -#define VOLUME_NAME_DOS 0x0 -#endif -#ifndef VOLUME_NAME_NT -#define VOLUME_NAME_NT 0x2 -#endif #ifndef IO_REPARSE_TAG_SYMLINK #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) #endif @@ -3731,11 +3725,10 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/ { HANDLE hFile; - int buf_size; - wchar_t *target_path; + wchar_t buf[MAXPATHLEN], *target_path = buf; + int buf_size = Py_ARRAY_LENGTH(buf); int result_length; PyObject *result; - const char *err = NULL; Py_BEGIN_ALLOW_THREADS hFile = CreateFileW( @@ -3747,55 +3740,52 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ FILE_FLAG_BACKUP_SEMANTICS, NULL); + Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { - err = "CreateFileW"; - goto done1; + return win32_error_object("CreateFileW", path->object); } /* We have a good handle to the target, use it to determine the target path name. */ - buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); + while (1) { + Py_BEGIN_ALLOW_THREADS + result_length = GetFinalPathNameByHandleW(hFile, target_path, + buf_size, VOLUME_NAME_DOS); + Py_END_ALLOW_THREADS - if (!buf_size) { - err = "GetFinalPathNameByHandle"; - goto done1; - } -done1: - Py_END_ALLOW_THREADS - if (err) - return win32_error_object(err, path->object); + if (!result_length) { + result = win32_error_object("GetFinalPathNameByHandleW", + path->object); + goto cleanup; + } - target_path = PyMem_New(wchar_t, buf_size+1); - if(!target_path) - return PyErr_NoMemory(); + if (result_length < buf_size) { + break; + } - Py_BEGIN_ALLOW_THREADS - result_length = GetFinalPathNameByHandleW(hFile, target_path, - buf_size, VOLUME_NAME_DOS); - if (!result_length) { - err = "GetFinalPathNameByHandle"; - goto done2; + wchar_t *tmp; + tmp = PyMem_Realloc(target_path != buf ? target_path : NULL, + result_length * sizeof(*tmp)); + if (!tmp) { + result = PyErr_NoMemory(); + goto cleanup; + } + + buf_size = result_length; + target_path = tmp; } - if (!CloseHandle(hFile)) { - err = "CloseHandle"; - goto done2; - } -done2: - Py_END_ALLOW_THREADS - if (err) { - PyMem_Free(target_path); - return win32_error_object(err, path->object); - } - - target_path[result_length] = 0; result = PyUnicode_FromWideChar(target_path, result_length); - PyMem_Free(target_path); if (path->narrow) Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); - return result; +cleanup: + if (target_path != buf) { + PyMem_Free(target_path); + } + CloseHandle(hFile); + return result; } /*[clinic input]