summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorAlexey Izbyshev <izbyshev@users.noreply.github.com>2018-03-08 16:03:25 (GMT)
committerSteve Dower <steve.dower@microsoft.com>2018-03-08 16:03:25 (GMT)
commit3b20d3454e8082e07dba93617793de5dc9237828 (patch)
treea11e2e29cf9b912fe006e1b9b1c3a37ea9529352 /Modules
parent3c7ac7ea2098c672e50402d1d1b5ee9f14586437 (diff)
downloadcpython-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.c74
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]