From 1a1ff29659f068659dea07f1bd67b8fd4331071c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 16 Feb 2015 13:28:22 +0200 Subject: [PATCH] Issue #23446: Use PyMem_New instead of PyMem_Malloc to avoid possible integer overflows. Added few missed PyErr_NoMemory(). --- Modules/_ctypes/_ctypes.c | 9 ++++++--- Modules/_ctypes/stgdict.c | 12 ++++++++---- Modules/_localemodule.c | 2 +- Modules/_ssl.c | 7 ++++--- Modules/_testbuffer.c | 2 +- Modules/_testcapimodule.c | 2 +- Modules/getpath.c | 2 +- Modules/posixmodule.c | 18 +++++++++--------- Modules/pyexpat.c | 4 ++-- Modules/socketmodule.c | 6 ++++-- Modules/unicodedata.c | 4 ++-- Modules/zipimport.c | 2 +- Objects/unicodeobject.c | 22 +++++----------------- PC/winreg.c | 6 +++--- Python/peephole.c | 4 ++-- 15 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index c2889d2ec3b..14ec4ce60c3 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4305,8 +4305,11 @@ Array_subscript(PyObject *myself, PyObject *item) slicelen); } - dest = (wchar_t *)PyMem_Malloc( - slicelen * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, slicelen); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } for (cur = start, i = 0; i < slicelen; cur += step, i++) { @@ -4986,7 +4989,7 @@ Pointer_subscript(PyObject *myself, PyObject *item) return PyUnicode_FromWideChar(ptr + start, len); } - dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, len); if (dest == NULL) return PyErr_NoMemory(); for (cur = start, i = 0; i < len; cur += step, i++) { diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 728f75183fb..879afb8424f 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -76,14 +76,18 @@ PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) if (src->format) { dst->format = PyMem_Malloc(strlen(src->format) + 1); - if (dst->format == NULL) + if (dst->format == NULL) { + PyErr_NoMemory(); return -1; + } strcpy(dst->format, src->format); } if (src->shape) { dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim); - if (dst->shape == NULL) + if (dst->shape == NULL) { + PyErr_NoMemory(); return -1; + } memcpy(dst->shape, src->shape, sizeof(Py_ssize_t) * src->ndim); } @@ -380,7 +384,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = align ? align : 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; @@ -398,7 +402,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 400c3448bab..b1d6add477a 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -254,7 +254,7 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) /* assume no change in size, first */ n1 = n1 + 1; - buf = PyMem_Malloc(n1 * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, n1); if (!buf) { PyErr_NoMemory(); goto exit; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 914d5aa6fa5..95397106029 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3838,10 +3838,11 @@ static int _setup_ssl_threads(void) { if (_ssl_locks == NULL) { _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = (PyThread_type_lock *) - PyMem_Malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); - if (_ssl_locks == NULL) + _ssl_locks = PyMem_New(PyThread_type_lock, _ssl_locks_count); + if (_ssl_locks == NULL) { + PyErr_NoMemory(); return 0; + } memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); for (i = 0; i < _ssl_locks_count; i++) { diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 0c6ef16f175..176df7c5ba3 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -850,7 +850,7 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) Py_ssize_t *dest; Py_ssize_t x, i; - dest = PyMem_Malloc(len * (sizeof *dest)); + dest = PyMem_New(Py_ssize_t, len); if (dest == NULL) { PyErr_NoMemory(); return NULL; diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 625409e56f6..cf4b0e14f01 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1516,7 +1516,7 @@ unicode_aswidechar(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) return NULL; - buffer = PyMem_Malloc(buflen * sizeof(wchar_t)); + buffer = PyMem_New(wchar_t, buflen); if (buffer == NULL) return PyErr_NoMemory(); diff --git a/Modules/getpath.c b/Modules/getpath.c index c057737ec2b..13e38172607 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -735,7 +735,7 @@ calculate_path(void) bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; - buf = (wchar_t *)PyMem_Malloc(bufsz * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, bufsz); if (buf == NULL) { Py_FatalError( "Not enough memory for dynamic PYTHONPATH"); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 628dec29d7a..d45f59e5f1b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1638,7 +1638,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path) if(!buf_size) return FALSE; - buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + buf = PyMem_New(wchar_t, buf_size+1); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; @@ -3627,7 +3627,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) len = wcslen(path->wide); } /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t)); + wnamebuf = PyMem_New(wchar_t, len + 5); if (!wnamebuf) { PyErr_NoMemory(); goto exit; @@ -3917,7 +3917,7 @@ posix__getfullpathname(PyObject *self, PyObject *args) Py_ARRAY_LENGTH(woutbuf), woutbuf, &wtemp); if (result > Py_ARRAY_LENGTH(woutbuf)) { - woutbufp = PyMem_Malloc(result * sizeof(wchar_t)); + woutbufp = PyMem_New(wchar_t, result); if (!woutbufp) return PyErr_NoMemory(); result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); @@ -3997,7 +3997,7 @@ posix__getfinalpathname(PyObject *self, PyObject *args) if(!buf_size) return win32_error_object("GetFinalPathNameByHandle", po); - target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + target_path = PyMem_New(wchar_t, buf_size+1); if(!target_path) return PyErr_NoMemory(); @@ -4082,7 +4082,7 @@ posix__getvolumepathname(PyObject *self, PyObject *args) return NULL; } - mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t)); + mountpath = PyMem_New(wchar_t, buflen); if (mountpath == NULL) return PyErr_NoMemory(); @@ -6213,9 +6213,9 @@ posix_getgrouplist(PyObject *self, PyObject *args) #endif #ifdef __APPLE__ - groups = PyMem_Malloc(ngroups * sizeof(int)); + groups = PyMem_New(int, ngroups); #else - groups = PyMem_Malloc(ngroups * sizeof(gid_t)); + groups = PyMem_New(gid_t, ngroups); #endif if (groups == NULL) return PyErr_NoMemory(); @@ -6293,7 +6293,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* groups will fit in existing array */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6319,7 +6319,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* Avoid malloc(0) */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 4ced53b611a..19be0c7cc52 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -928,7 +928,7 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - new_parser->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + new_parser->handlers = PyMem_New(PyObject *, i); if (!new_parser->handlers) { Py_DECREF(new_parser); return PyErr_NoMemory(); @@ -1121,7 +1121,7 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - self->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + self->handlers = PyMem_New(PyObject *, i); if (!self->handlers) { Py_DECREF(self); return PyErr_NoMemory(); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index cb44d05b620..e9feba378e6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4126,9 +4126,11 @@ socket_gethostname(PyObject *self, PyObject *unused) /* MSDN says ERROR_MORE_DATA may occur because DNS allows longer names */ - name = PyMem_Malloc(size * sizeof(wchar_t)); - if (!name) + name = PyMem_New(wchar_t, size); + if (!name) { + PyErr_NoMemory(); return NULL; + } if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, name, &size)) diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index ec70e7af9db..47d2937b810 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -556,7 +556,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) /* Overallocate at most 10 characters. */ space = (isize > 10 ? 10 : isize) + isize; osize = space; - output = PyMem_Malloc(space * sizeof(Py_UCS4)); + output = PyMem_New(Py_UCS4, space); if (!output) { PyErr_NoMemory(); return NULL; @@ -703,7 +703,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) /* We allocate a buffer for the output. If we find that we made no changes, we still return the NFD result. */ - output = PyMem_Malloc(len * sizeof(Py_UCS4)); + output = PyMem_New(Py_UCS4, len); if (!output) { PyErr_NoMemory(); Py_DECREF(result); diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 8fe919539fd..f2cc245b7d8 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -233,7 +233,7 @@ make_filename(PyObject *prefix, PyObject *name) Py_ssize_t len; len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1; - p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len); + p = buf = PyMem_New(Py_UCS4, len); if (buf == NULL) { PyErr_NoMemory(); return NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 84ab6a114cd..2ffa55b96ba 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2186,7 +2186,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) } switch (kind) { case PyUnicode_2BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS2)); + result = PyMem_New(Py_UCS2, len); if (!result) return PyErr_NoMemory(); assert(skind == PyUnicode_1BYTE_KIND); @@ -2197,7 +2197,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) result); return result; case PyUnicode_4BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS4)); + result = PyMem_New(Py_UCS4, len); if (!result) return PyErr_NoMemory(); if (skind == PyUnicode_2BYTE_KIND) { @@ -2239,11 +2239,7 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, if (copy_null) targetlen++; if (!target) { - if (PY_SSIZE_T_MAX / sizeof(Py_UCS4) < targetlen) { - PyErr_NoMemory(); - return NULL; - } - target = PyMem_Malloc(targetlen * sizeof(Py_UCS4)); + target = PyMem_New(Py_UCS4, targetlen); if (!target) { PyErr_NoMemory(); return NULL; @@ -2852,12 +2848,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, buflen = unicode_aswidechar(unicode, NULL, 0); if (buflen == -1) return NULL; - if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { - PyErr_NoMemory(); - return NULL; - } - - buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); + buffer = PyMem_NEW(wchar_t, buflen); if (buffer == NULL) { PyErr_NoMemory(); return NULL; @@ -3550,10 +3541,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, wstr = smallbuf; } else { - if (wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) - return PyErr_NoMemory(); - - wstr = PyMem_Malloc((wlen+1) * sizeof(wchar_t)); + wstr = PyMem_New(wchar_t, wlen+1); if (!wstr) return PyErr_NoMemory(); } diff --git a/PC/winreg.c b/PC/winreg.c index 63c437e437e..19d5a703918 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -939,7 +939,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) wchar_t *data = (wchar_t *)retDataBuf; int len = retDataSize / 2; int s = countStrings(data, len); - wchar_t **str = (wchar_t **)PyMem_Malloc(sizeof(wchar_t *)*s); + wchar_t **str = PyMem_New(wchar_t *, s); if (str == NULL) return PyErr_NoMemory(); @@ -1206,7 +1206,7 @@ PyEnumValue(PyObject *self, PyObject *args) ++retDataSize; bufDataSize = retDataSize; bufValueSize = retValueSize; - retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); + retValueBuf = PyMem_New(wchar_t, retValueSize); if (retValueBuf == NULL) return PyErr_NoMemory(); retDataBuf = (BYTE *)PyMem_Malloc(retDataSize); @@ -1277,7 +1277,7 @@ PyExpandEnvironmentStrings(PyObject *self, PyObject *args) return PyErr_SetFromWindowsErrWithFunction(retValueSize, "ExpandEnvironmentStrings"); } - retValue = (wchar_t *)PyMem_Malloc(retValueSize * sizeof(wchar_t)); + retValue = PyMem_New(wchar_t, retValueSize); if (retValue == NULL) { return PyErr_NoMemory(); } diff --git a/Python/peephole.c b/Python/peephole.c index 4185462b34a..c56c8fcc23e 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -290,7 +290,7 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts, PyObject *v static unsigned int * markblocks(unsigned char *code, Py_ssize_t len) { - unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int)); + unsigned int *blocks = PyMem_New(unsigned int, len); int i,j, opcode, blockcnt = 0; if (blocks == NULL) { @@ -398,7 +398,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, goto exitUnchanged; /* Mapping to new jump targets after NOPs are removed */ - addrmap = (int *)PyMem_Malloc(codelen * sizeof(int)); + addrmap = PyMem_New(int, codelen); if (addrmap == NULL) { PyErr_NoMemory(); goto exitError;