]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],
authorChristian Heimes <christian@cheimes.de>
Mon, 22 Jul 2013 10:53:32 +0000 (12:53 +0200)
committerChristian Heimes <christian@cheimes.de>
Mon, 22 Jul 2013 10:53:32 +0000 (12:53 +0200)
prefix and exec_prefix if the operation system does not obey MAXPATHLEN.

Misc/NEWS
Modules/getpath.c
Python/sysmodule.c

index 3092e323bffe2c5d9c4e4cd15d9d0dd21fe84b65..2b28991c5142abd35c9057b2fa663c5607d98e59 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.3.3 release candidate 1?
 Core and Builtins
 -----------------
 
+- Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],
+  prefix and exec_prefix if the operation system does not obey MAXPATHLEN.
+
 - Issue #18344: Fix potential ref-leaks in _bufferedreader_read_all().
 
 - Issue #17872: Fix a segfault in marshal.load() when input stream returns
index b98c52012d7df7b10b245e1c85036e6e4d024409..ff14fdd6cd3472ccdfcf3d6ab9237e53c561e67d 100644 (file)
@@ -326,6 +326,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
     if (home) {
         wchar_t *delim;
         wcsncpy(prefix, home, MAXPATHLEN);
+        prefix[MAXPATHLEN] = L'\0';
         delim = wcschr(prefix, DELIM);
         if (delim)
             *delim = L'\0';
@@ -335,13 +336,15 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
     }
 
     /* Check to see if argv[0] is in the build directory */
-    wcscpy(prefix, argv0_path);
+    wcsncpy(prefix, argv0_path, MAXPATHLEN);
+    prefix[MAXPATHLEN] = L'\0';
     joinpath(prefix, L"Modules/Setup");
     if (isfile(prefix)) {
         /* Check VPATH to see if argv0_path is in the build directory. */
         vpath = _Py_char2wchar(VPATH, NULL);
         if (vpath != NULL) {
-            wcscpy(prefix, argv0_path);
+            wcsncpy(prefix, argv0_path, MAXPATHLEN);
+            prefix[MAXPATHLEN] = L'\0';
             joinpath(prefix, vpath);
             PyMem_Free(vpath);
             joinpath(prefix, L"Lib");
@@ -365,6 +368,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
 
     /* Look at configure's PREFIX */
     wcsncpy(prefix, _prefix, MAXPATHLEN);
+    prefix[MAXPATHLEN] = L'\0';
     joinpath(prefix, lib_python);
     joinpath(prefix, LANDMARK);
     if (ismodule(prefix))
@@ -391,6 +395,7 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
             wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
         else
             wcsncpy(exec_prefix, home, MAXPATHLEN);
+        exec_prefix[MAXPATHLEN] = L'\0';
         joinpath(exec_prefix, lib_python);
         joinpath(exec_prefix, L"lib-dynload");
         return 1;
@@ -399,7 +404,8 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
     /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
        is written by setup.py and contains the relative path to the location
        of shared library modules. */
-    wcscpy(exec_prefix, argv0_path);
+    wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
+    exec_prefix[MAXPATHLEN] = L'\0';
     joinpath(exec_prefix, L"pybuilddir.txt");
     if (isfile(exec_prefix)) {
         FILE *f = _Py_wfopen(exec_prefix, L"rb");
@@ -420,7 +426,8 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
                 Py_DECREF(decoded);
                 if (k >= 0) {
                     rel_builddir_path[k] = L'\0';
-                    wcscpy(exec_prefix, argv0_path);
+                    wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
+                    exec_prefix[MAXPATHLEN] = L'\0';
                     joinpath(exec_prefix, rel_builddir_path);
                     return -1;
                 }
@@ -442,6 +449,7 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
 
     /* Look at configure's EXEC_PREFIX */
     wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
+    exec_prefix[MAXPATHLEN] = L'\0';
     joinpath(exec_prefix, lib_python);
     joinpath(exec_prefix, L"lib-dynload");
     if (isdir(exec_prefix))
index 20bfa555b3d9175bdf0e7cb428cd6b2e7dd59fab..edd6649ae6dd7a92f4668c717cc8e717e39ff654 100644 (file)
@@ -1856,10 +1856,11 @@ sys_update_path(int argc, wchar_t **argv)
             if (q == NULL)
                 argv0 = link; /* argv0 without path */
             else {
-                /* Must make a copy */
-                wcscpy(argv0copy, argv0);
+                /* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */
+                wcsncpy(argv0copy, argv0, MAXPATHLEN);
                 q = wcsrchr(argv0copy, SEP);
-                wcscpy(q+1, link);
+                wcsncpy(q+1, link, MAXPATHLEN);
+                q[MAXPATHLEN + 1] = L'\0';
                 argv0 = argv0copy;
             }
         }