From f7eae0adfcd4c50034281b2c69f461b43b68db84 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 28 Jun 2017 08:30:06 +0300 Subject: [security] bpo-13617: Reject embedded null characters in wchar* strings. (#2302) Based on patch by Victor Stinner. Add private C API function _PyUnicode_AsUnicode() which is similar to PyUnicode_AsUnicode(), but checks for null characters. --- Python/dynload_win.c | 4 ++-- Python/fileutils.c | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'Python') diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 05050cf41d..0fdf77f552 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -190,13 +190,13 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { dl_funcptr p; char funcname[258], *import_python; - wchar_t *wpathname; + const wchar_t *wpathname; #ifndef _DEBUG _Py_CheckPython3(); #endif - wpathname = PyUnicode_AsUnicode(pathname); + wpathname = _PyUnicode_AsUnicode(pathname); if (wpathname == NULL) return NULL; diff --git a/Python/fileutils.c b/Python/fileutils.c index f3764e4b3c..97505e5bc6 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -711,21 +711,32 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; struct _stat wstatbuf; - wchar_t *wpath; + const wchar_t *wpath; - wpath = PyUnicode_AsUnicode(path); + wpath = _PyUnicode_AsUnicode(path); if (wpath == NULL) return -2; + err = _wstat(wpath, &wstatbuf); if (!err) statbuf->st_mode = wstatbuf.st_mode; return err; #else int ret; - PyObject *bytes = PyUnicode_EncodeFSDefault(path); + PyObject *bytes; + char *cpath; + + bytes = PyUnicode_EncodeFSDefault(path); if (bytes == NULL) return -2; - ret = stat(PyBytes_AS_STRING(bytes), statbuf); + + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) { + Py_DECREF(bytes); + return -2; + } + + ret = stat(cpath, statbuf); Py_DECREF(bytes); return ret; #endif @@ -1080,7 +1091,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) FILE *f; int async_err = 0; #ifdef MS_WINDOWS - wchar_t *wpath; + const wchar_t *wpath; wchar_t wmode[10]; int usize; @@ -1094,7 +1105,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } - wpath = PyUnicode_AsUnicode(path); + wpath = _PyUnicode_AsUnicode(path); if (wpath == NULL) return NULL; -- cgit v1.2.1