summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2013-07-22 10:53:32 (GMT)
committerChristian Heimes <christian@cheimes.de>2013-07-22 10:53:32 (GMT)
commit60a60677093e2792439c9e34debe6d55feead63f (patch)
tree89fc77fe5cdf82f498c990466ec0a69efa789d26
parent37c916dd18df3442a4d8f79d14f5f23ba87e3fe5 (diff)
downloadcpython-60a60677093e2792439c9e34debe6d55feead63f.zip
cpython-60a60677093e2792439c9e34debe6d55feead63f.tar.gz
cpython-60a60677093e2792439c9e34debe6d55feead63f.tar.bz2
Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],
prefix and exec_prefix if the operation system does not obey MAXPATHLEN.
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/getpath.c16
-rw-r--r--Python/sysmodule.c7
3 files changed, 19 insertions, 7 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 3092e32..2b28991 100644
--- 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
diff --git a/Modules/getpath.c b/Modules/getpath.c
index b98c520..ff14fdd 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -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))
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 20bfa55..edd6649 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -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;
}
}