This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2010年11月04日 11:27 by hfuru, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| getpath.diff | hfuru, 2010年11月04日 11:27 | getpath.c patches | ||
| Messages (7) | |||
|---|---|---|---|
| msg120390 - (view) | Author: Hallvard B Furuseth (hfuru) | Date: 2010年11月04日 11:27 | |
Patches for getpath.c in Python 2.7 and 3.2a3: 2.7 chunk#2: copy_absolute() would use uninitialized data if getcwd() failed. The fix is equivalent to what 3.2a3 does. 3.2a3 chunk#2: search_for_exec_prefix() did 'unsigned value >= 0' on the PyUnicode_AsWideChar() result. (The fix just renames n to k of signed type, and moves the variables. An outer uninitialized 'size_t n' is in scope, so renaming the inner n to k leaves 'n=fread()' still a size_t.) Chunk #1, both versions: Fix an unlikely 'n+k' wraparound bug while I'm at it. The code has just checked that MAXPATHLEN-n will not wrap. |
|||
| msg120711 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2010年11月08日 03:52 | |
3.2a3 chunk#2 cannot fail because PyUnicode_AsWideChar() only returns -1 if the first argument is NULL, whereas we just checked that decoded is not NULL. But it would be better to fix the variable type to avoid future bugs. |
|||
| msg120918 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2010年11月10日 14:27 | |
r86399 fixes the code checking PyUnicode_AsWideChar() failure. The following change is useless, it cannot overflow: - if (n + k > MAXPATHLEN) + if (k > MAXPATHLEN - n) k = MAXPATHLEN - n; n and k maximum values are MAXPATHLEN (and the maximum value of MAXPATHLEN is 4096), whereas n and k type maximum values are at least 2^31. |
|||
| msg120940 - (view) | Author: Hallvard B Furuseth (hfuru) | Date: 2010年11月11日 08:50 | |
STINNER Victor writes: > The following change is useless, it cannot overflow: > - if (n + k > MAXPATHLEN) > + if (k > MAXPATHLEN - n) > k = MAXPATHLEN - n; > > n and k maximum values are MAXPATHLEN (and the maximum value of > MAXPATHLEN is 4096), (...) OK. I could only tell that for n, not for k. But even so it would certainly be an unlikely overflow. |
|||
| msg241632 - (view) | Author: Mark Lawrence (BreamoreBoy) * | Date: 2015年04月20日 11:25 | |
Reading msg120918 and msg120940 it looks as if work has been completed so this can be closed as fixed. |
|||
| msg241688 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2015年04月20日 21:48 | |
> Reading msg120918 and msg120940 it looks as if work has been completed so this can be closed as fixed. Attached patch contains more fixes. |
|||
| msg336507 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2019年02月25日 10:10 | |
I reviewed getpath.diff:
diff -pru Python-2.7/Modules/getpath.c Python-2.7/Modules/getpath.c
--- Python-2.7/Modules/getpath.c
+++ Python-2.7/Modules/getpath.c
@@ -218,7 +218,7 @@ joinpath(char *buffer, char *stuff)
if (n > MAXPATHLEN)
Py_FatalError("buffer overflow in getpath.c's joinpath()");
k = strlen(stuff);
- if (n + k > MAXPATHLEN)
+ if (k > MAXPATHLEN - n)
k = MAXPATHLEN - n;
strncpy(buffer+n, stuff, k);
buffer[n+k] = '0円';
As I explained in a previous comment, this change is useless: "n+k" cannot overflow.
@@ -229,10 +229,9 @@ joinpath(char *buffer, char *stuff)
static void
copy_absolute(char *path, char *p)
{
- if (p[0] == SEP)
+ if (p[0] == SEP || getcwd(path, MAXPATHLEN) == NULL)
strcpy(path, p);
else {
- getcwd(path, MAXPATHLEN);
if (p[0] == '.' && p[1] == SEP)
p += 2;
joinpath(path, p);
The code changed in the meanwhile (in the master branch, in 3.7 maybe, I don't recall), getcwd() error is now checked in copy_absolute():
if (!_Py_wgetcwd(path, pathlen)) {
/* unable to get the current directory */
wcscpy(path, p);
return;
}
diff -pru Python-3.2a3/Modules/getpath.c Python-3.2a3/Modules/getpath.c
--- Python-3.2a3/Modules/getpath.c
+++ Python-3.2a3/Modules/getpath.c
@@ -351,18 +351,18 @@ search_for_exec_prefix(wchar_t *argv0_pa
else {
char buf[MAXPATHLEN+1];
PyObject *decoded;
- wchar_t rel_builddir_path[MAXPATHLEN+1];
- size_t n;
n = fread(buf, 1, MAXPATHLEN, f);
buf[n] = '0円';
fclose(f);
decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
if (decoded != NULL) {
- n = PyUnicode_AsWideChar((PyUnicodeObject*)decoded,
+ wchar_t rel_builddir_path[MAXPATHLEN+1];
+ Py_ssize_t k;
+ k = PyUnicode_AsWideChar((PyUnicodeObject*)decoded,
rel_builddir_path, MAXPATHLEN);
Py_DECREF(decoded);
- if (n >= 0) {
- rel_builddir_path[n] = L'0円';
+ if (k >= 0) {
+ rel_builddir_path[k] = L'0円';
wcscpy(exec_prefix, argv0_path);
joinpath(exec_prefix, rel_builddir_path);
return -1;
Again, the code changed in the meanwhile:
wchar_t *rel_builddir_path;
...
rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n);
if (rel_builddir_path) {
There is a new _Py_DecodeUTF8_surrogateescape() function which returns directly wchar_t* strings.
I close the issue.
--
Modules/getpath.c should be rewritten without global MAXPATHLEN limit. I rewrote the code to avoid global variables and pass buffer lengths in some functions. It's better but not perfect yet :-))
|
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:08 | admin | set | github: 54517 |
| 2019年02月25日 10:10:23 | vstinner | set | status: open -> closed resolution: fixed messages: + msg336507 stage: resolved |
| 2019年02月24日 23:02:42 | BreamoreBoy | set | nosy:
- BreamoreBoy |
| 2015年04月20日 21:48:22 | vstinner | set | messages: + msg241688 |
| 2015年04月20日 11:25:26 | BreamoreBoy | set | nosy:
+ BreamoreBoy messages: + msg241632 |
| 2010年11月11日 08:50:32 | hfuru | set | messages: + msg120940 |
| 2010年11月10日 14:27:36 | vstinner | set | messages: + msg120918 |
| 2010年11月08日 03:52:47 | vstinner | set | messages: + msg120711 |
| 2010年11月04日 13:14:44 | hfuru | set | versions: + Python 3.1, Python 2.7 |
| 2010年11月04日 11:54:41 | vstinner | set | nosy:
+ vstinner |
| 2010年11月04日 11:27:41 | hfuru | create | |