diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-06-28 05:30:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-28 05:30:06 (GMT) |
commit | f7eae0adfcd4c50034281b2c69f461b43b68db84 (patch) | |
tree | 02d6a582fd81f615e71c55365f1b37a774fc0a4e /Modules | |
parent | 592eda123329bb5ce2bffcbe3701be6b909f1b2a (diff) | |
download | cpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.zip cpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.tar.gz cpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.tar.bz2 |
[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.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/callproc.c | 5 | ||||
-rw-r--r-- | Modules/_cursesmodule.c | 10 | ||||
-rw-r--r-- | Modules/_io/fileio.c | 3 | ||||
-rw-r--r-- | Modules/_localemodule.c | 5 | ||||
-rw-r--r-- | Modules/grpmodule.c | 1 | ||||
-rw-r--r-- | Modules/nismodule.c | 1 | ||||
-rw-r--r-- | Modules/posixmodule.c | 18 | ||||
-rw-r--r-- | Modules/pwdmodule.c | 1 | ||||
-rw-r--r-- | Modules/spwdmodule.c | 1 |
9 files changed, 35 insertions, 10 deletions
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 5439b93..6990a76 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1253,10 +1253,11 @@ static PyObject *load_library(PyObject *self, PyObject *args) PyObject *nameobj; PyObject *ignored; HMODULE hMod; - if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored)) + + if (!PyArg_ParseTuple(args, "U|O:LoadLibrary", &nameobj, &ignored)) return NULL; - name = PyUnicode_AsUnicode(nameobj); + name = _PyUnicode_AsUnicode(nameobj); if (!name) return NULL; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 5dc0865..a709151 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -341,9 +341,11 @@ static int PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, PyObject **bytes, wchar_t **wstr) { + char *str; if (PyUnicode_Check(obj)) { #ifdef HAVE_NCURSESW assert (wstr != NULL); + *wstr = PyUnicode_AsWideCharString(obj, NULL); if (*wstr == NULL) return 0; @@ -353,12 +355,20 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL); if (*bytes == NULL) return 0; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { + return 0; + } return 1; #endif } else if (PyBytes_Check(obj)) { Py_INCREF(obj); *bytes = obj; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { + return 0; + } return 1; } diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index a09c39f7..cc7061f 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -271,11 +271,10 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, if (fd < 0) { #ifdef MS_WINDOWS - Py_ssize_t length; if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { return -1; } - widename = PyUnicode_AsUnicodeAndSize(stringobj, &length); + widename = PyUnicode_AsUnicode(stringobj); if (widename == NULL) return -1; #else diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index ecd673e..e364668 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -252,6 +252,11 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) s = PyUnicode_AsWideCharString(str, &n1); if (s == NULL) goto exit; + if (wcslen(s) != (size_t)n1) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + goto exit; + } /* assume no change in size, first */ n1 = n1 + 1; diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 9437ae7..f577fd3 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -151,6 +151,7 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) goto out; diff --git a/Modules/nismodule.c b/Modules/nismodule.c index b6a855c..a9028bb 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -169,6 +169,7 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict) return NULL; if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) { Py_DECREF(bkey); return NULL; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1c75eae..194a2b5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3757,7 +3757,7 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path) PyObject *result; const wchar_t *path_wchar; - path_wchar = PyUnicode_AsUnicode(path); + path_wchar = _PyUnicode_AsUnicode(path); if (path_wchar == NULL) return NULL; @@ -7209,7 +7209,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) )) return NULL; - path = PyUnicode_AsUnicode(po); + path = _PyUnicode_AsUnicode(po); if (path == NULL) return NULL; @@ -9002,6 +9002,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ { const wchar_t *env; + Py_ssize_t size; /* Search from index 1 because on Windows starting '=' is allowed for defining hidden environment variables. */ @@ -9015,16 +9016,21 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) if (unicode == NULL) { return NULL; } - if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { + + env = PyUnicode_AsUnicodeAndSize(unicode, &size); + if (env == NULL) + goto error; + if (size > _MAX_ENV) { PyErr_Format(PyExc_ValueError, "the environment variable is longer than %u characters", _MAX_ENV); goto error; } - - env = PyUnicode_AsUnicode(unicode); - if (env == NULL) + if (wcslen(env) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); goto error; + } + if (_wputenv(env)) { posix_error(); goto error; diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 784e9d0..bbef2de 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -158,6 +158,7 @@ pwd_getpwnam_impl(PyObject *module, PyObject *arg) if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) goto out; if ((p = getpwnam(name)) == NULL) { diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 556a715..1601ec0 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -134,6 +134,7 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg) if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) goto out; if ((p = getspnam(name)) == NULL) { |