]> granicus.if.org Git - python/commitdiff
bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 8 Mar 2018 16:26:43 +0000 (08:26 -0800)
committerGitHub <noreply@github.com>
Thu, 8 Mar 2018 16:26:43 +0000 (08:26 -0800)
(cherry picked from commit 3b20d3454e8082e07dba93617793de5dc9237828)

Co-authored-by: Alexey Izbyshev <izbyshev@users.noreply.github.com>
Misc/NEWS.d/next/Windows/2018-03-07-01-33-33.bpo-33016.Z_Med0.rst [new file with mode: 0644]
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 (file)
index 0000000..f4f78d4
--- /dev/null
@@ -0,0 +1 @@
+Fix potential use of uninitialized memory in nt._getfinalpathname
index 6bf8c6ba7b7a7183babdd1437e9f823301f395a4..e8964ce339015032a2385671c09b9aa4805bc11e 100644 (file)
@@ -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]