[Python-checkins] bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (GH-6010)

Miss Islington (bot) webhook-mailer at python.org
Thu Mar 8 11:26:46 EST 2018


https://github.com/python/cpython/commit/8c163bbf370f6f6cedd2c07f7d54c9b36c97d8f2
commit: 8c163bbf370f6f6cedd2c07f7d54c9b36c97d8f2
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-03-08T08:26:43-08:00
summary:

bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (GH-6010)

(cherry picked from commit 3b20d3454e8082e07dba93617793de5dc9237828)

Co-authored-by: Alexey Izbyshev <izbyshev at users.noreply.github.com>

files:
A Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst
M Modules/posixmodule.c

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 000000000000..f4f78d489bf1
--- /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 6bf8c6ba7b7a..e8964ce33901 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]



More information about the Python-checkins mailing list