Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de0e63b

Browse files
committed
Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],
prefix and exec_prefix if the operation system does not obey MAXPATHLEN.
2 parents 7fca717 + 60a6067 commit de0e63b

3 files changed

Lines changed: 19 additions & 7 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0],
14+
prefix and exec_prefix if the operation system does not obey MAXPATHLEN.
15+
1316
- Issue #18408: Fix many various bugs in code handling errors, especially
1417
on memory allocation failure (MemoryError).
1518

Modules/getpath.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
326326
if (home) {
327327
wchar_t *delim;
328328
wcsncpy(prefix, home, MAXPATHLEN);
329+
prefix[MAXPATHLEN] = L'\0';
329330
delim = wcschr(prefix, DELIM);
330331
if (delim)
331332
*delim = L'\0';
@@ -335,13 +336,15 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
335336
}
336337

337338
/* Check to see if argv[0] is in the build directory */
338-
wcscpy(prefix, argv0_path);
339+
wcsncpy(prefix, argv0_path, MAXPATHLEN);
340+
prefix[MAXPATHLEN] = L'\0';
339341
joinpath(prefix, L"Modules/Setup");
340342
if (isfile(prefix)) {
341343
/* Check VPATH to see if argv0_path is in the build directory. */
342344
vpath = _Py_char2wchar(VPATH, NULL);
343345
if (vpath != NULL) {
344-
wcscpy(prefix, argv0_path);
346+
wcsncpy(prefix, argv0_path, MAXPATHLEN);
347+
prefix[MAXPATHLEN] = L'\0';
345348
joinpath(prefix, vpath);
346349
PyMem_RawFree(vpath);
347350
joinpath(prefix, L"Lib");
@@ -365,6 +368,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
365368

366369
/* Look at configure's PREFIX */
367370
wcsncpy(prefix, _prefix, MAXPATHLEN);
371+
prefix[MAXPATHLEN] = L'\0';
368372
joinpath(prefix, lib_python);
369373
joinpath(prefix, LANDMARK);
370374
if (ismodule(prefix))
@@ -391,6 +395,7 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
391395
wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
392396
else
393397
wcsncpy(exec_prefix, home, MAXPATHLEN);
398+
exec_prefix[MAXPATHLEN] = L'\0';
394399
joinpath(exec_prefix, lib_python);
395400
joinpath(exec_prefix, L"lib-dynload");
396401
return 1;
@@ -399,7 +404,8 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
399404
/* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
400405
is written by setup.py and contains the relative path to the location
401406
of shared library modules. */
402-
wcscpy(exec_prefix, argv0_path);
407+
wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
408+
exec_prefix[MAXPATHLEN] = L'\0';
403409
joinpath(exec_prefix, L"pybuilddir.txt");
404410
if (isfile(exec_prefix)) {
405411
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
420426
Py_DECREF(decoded);
421427
if (k >= 0) {
422428
rel_builddir_path[k] = L'\0';
423-
wcscpy(exec_prefix, argv0_path);
429+
wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
430+
exec_prefix[MAXPATHLEN] = L'\0';
424431
joinpath(exec_prefix, rel_builddir_path);
425432
return -1;
426433
}
@@ -442,6 +449,7 @@ search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix
442449

443450
/* Look at configure's EXEC_PREFIX */
444451
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
452+
exec_prefix[MAXPATHLEN] = L'\0';
445453
joinpath(exec_prefix, lib_python);
446454
joinpath(exec_prefix, L"lib-dynload");
447455
if (isdir(exec_prefix))

Python/sysmodule.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,10 +1854,11 @@ sys_update_path(int argc, wchar_t **argv)
18541854
if (q == NULL)
18551855
argv0 = link; /* argv0 without path */
18561856
else {
1857-
/* Must make a copy */
1858-
wcscpy(argv0copy, argv0);
1857+
/* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */
1858+
wcsncpy(argv0copy, argv0, MAXPATHLEN);
18591859
q = wcsrchr(argv0copy, SEP);
1860-
wcscpy(q+1, link);
1860+
wcsncpy(q+1, link, MAXPATHLEN);
1861+
q[MAXPATHLEN + 1] = L'\0';
18611862
argv0 = argv0copy;
18621863
}
18631864
}

0 commit comments

Comments
 (0)