diff options
author | Alexey Izbyshev <izbyshev@users.noreply.github.com> | 2018-03-08 16:03:25 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2018-03-08 16:03:25 (GMT) |
commit | 3b20d3454e8082e07dba93617793de5dc9237828 (patch) | |
tree | a11e2e29cf9b912fe006e1b9b1c3a37ea9529352 /Modules | |
parent | 3c7ac7ea2098c672e50402d1d1b5ee9f14586437 (diff) | |
download | cpython-3b20d3454e8082e07dba93617793de5dc9237828.zip cpython-3b20d3454e8082e07dba93617793de5dc9237828.tar.gz cpython-3b20d3454e8082e07dba93617793de5dc9237828.tar.bz2 |
bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (#6010)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 74 |
1 files changed, 32 insertions, 42 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f4c0104..e672103 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 <process.h> #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; + } - 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); + buf_size = result_length; + target_path = tmp; } - 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] |