Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],

prefix and exec_prefix if the operation system does not obey MAXPATHLEN.
This commit is contained in:
Christian Heimes 2013-07-22 12:54:21 +02:00
commit de0e63bd9c
3 changed files with 19 additions and 7 deletions

View File

@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins 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 #18408: Fix many various bugs in code handling errors, especially - Issue #18408: Fix many various bugs in code handling errors, especially
on memory allocation failure (MemoryError). on memory allocation failure (MemoryError).

View File

@ -326,6 +326,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
if (home) { if (home) {
wchar_t *delim; wchar_t *delim;
wcsncpy(prefix, home, MAXPATHLEN); wcsncpy(prefix, home, MAXPATHLEN);
prefix[MAXPATHLEN] = L'\0';
delim = wcschr(prefix, DELIM); delim = wcschr(prefix, DELIM);
if (delim) if (delim)
*delim = L'\0'; *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 */ /* 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"); joinpath(prefix, L"Modules/Setup");
if (isfile(prefix)) { if (isfile(prefix)) {
/* Check VPATH to see if argv0_path is in the build directory. */ /* Check VPATH to see if argv0_path is in the build directory. */
vpath = _Py_char2wchar(VPATH, NULL); vpath = _Py_char2wchar(VPATH, NULL);
if (vpath != NULL) { if (vpath != NULL) {
wcscpy(prefix, argv0_path); wcsncpy(prefix, argv0_path, MAXPATHLEN);
prefix[MAXPATHLEN] = L'\0';
joinpath(prefix, vpath); joinpath(prefix, vpath);
PyMem_RawFree(vpath); PyMem_RawFree(vpath);
joinpath(prefix, L"Lib"); 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 */ /* Look at configure's PREFIX */
wcsncpy(prefix, _prefix, MAXPATHLEN); wcsncpy(prefix, _prefix, MAXPATHLEN);
prefix[MAXPATHLEN] = L'\0';
joinpath(prefix, lib_python); joinpath(prefix, lib_python);
joinpath(prefix, LANDMARK); joinpath(prefix, LANDMARK);
if (ismodule(prefix)) 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); wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
else else
wcsncpy(exec_prefix, home, MAXPATHLEN); wcsncpy(exec_prefix, home, MAXPATHLEN);
exec_prefix[MAXPATHLEN] = L'\0';
joinpath(exec_prefix, lib_python); joinpath(exec_prefix, lib_python);
joinpath(exec_prefix, L"lib-dynload"); joinpath(exec_prefix, L"lib-dynload");
return 1; 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" /* 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 is written by setup.py and contains the relative path to the location
of shared library modules. */ 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"); joinpath(exec_prefix, L"pybuilddir.txt");
if (isfile(exec_prefix)) { if (isfile(exec_prefix)) {
FILE *f = _Py_wfopen(exec_prefix, L"rb"); 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); Py_DECREF(decoded);
if (k >= 0) { if (k >= 0) {
rel_builddir_path[k] = L'\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); joinpath(exec_prefix, rel_builddir_path);
return -1; 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 */ /* Look at configure's EXEC_PREFIX */
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
exec_prefix[MAXPATHLEN] = L'\0';
joinpath(exec_prefix, lib_python); joinpath(exec_prefix, lib_python);
joinpath(exec_prefix, L"lib-dynload"); joinpath(exec_prefix, L"lib-dynload");
if (isdir(exec_prefix)) if (isdir(exec_prefix))

View File

@ -1854,10 +1854,11 @@ sys_update_path(int argc, wchar_t **argv)
if (q == NULL) if (q == NULL)
argv0 = link; /* argv0 without path */ argv0 = link; /* argv0 without path */
else { else {
/* Must make a copy */ /* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */
wcscpy(argv0copy, argv0); wcsncpy(argv0copy, argv0, MAXPATHLEN);
q = wcsrchr(argv0copy, SEP); q = wcsrchr(argv0copy, SEP);
wcscpy(q+1, link); wcsncpy(q+1, link, MAXPATHLEN);
q[MAXPATHLEN + 1] = L'\0';
argv0 = argv0copy; argv0 = argv0copy;
} }
} }