diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2008-08-24 07:08:55 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2008-08-24 07:08:55 (GMT) |
commit | 3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f (patch) | |
tree | c29add3a6b61f321009d73a91464f45b5d10862a /Objects | |
parent | 06db799a53cba0396908d291bbe4bcc6c1c50daa (diff) | |
download | cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.zip cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.tar.gz cpython-3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f.tar.bz2 |
Closes release blocker #3627.
Merged revisions 65335 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
TESTED=./python -E -tt ./Lib/test/regrtest.py -uall (both debug and opt)
........
r65335 | neal.norwitz | 2008-07-31 10:17:14 -0700 (Thu, 31 Jul 2008) | 1 line
Security patches from Apple: prevent int overflow when allocating memory
........
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/bytearrayobject.c | 5 | ||||
-rw-r--r-- | Objects/bytesobject.c | 8 | ||||
-rw-r--r-- | Objects/longobject.c | 2 | ||||
-rw-r--r-- | Objects/tupleobject.c | 5 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 62 |
5 files changed, 66 insertions, 16 deletions
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index da11249..201d294 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -121,6 +121,11 @@ PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) return NULL; } + /* Prevent buffer overflow when setting alloc to size+1. */ + if (size == PY_SSIZE_T_MAX) { + return PyErr_NoMemory(); + } + new = PyObject_New(PyByteArrayObject, &PyByteArray_Type); if (new == NULL) return NULL; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index bfb4ff8..24228ea 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -83,6 +83,12 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) return (PyObject *)op; } + if (size > PY_SSIZE_T_MAX - sizeof(PyBytesObject)) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too large"); + return NULL; + } + /* Inline PyObject_NewVar */ op = (PyBytesObject *)PyObject_MALLOC(sizeof(PyBytesObject) + size); if (op == NULL) @@ -111,7 +117,7 @@ PyBytes_FromString(const char *str) assert(str != NULL); size = strlen(str); - if (size > PY_SSIZE_T_MAX) { + if (size > PY_SSIZE_T_MAX - sizeof(PyBytesObject)) { PyErr_SetString(PyExc_OverflowError, "byte string is too long"); return NULL; diff --git a/Objects/longobject.c b/Objects/longobject.c index 3aa518b..8f7ad4c 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -139,6 +139,8 @@ _PyLong_New(Py_ssize_t size) PyErr_NoMemory(); return NULL; } + /* XXX(nnorwitz): This can overflow -- + PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect overflow */ return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 7ff957e..963d90e 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -60,11 +60,12 @@ PyTuple_New(register Py_ssize_t size) Py_ssize_t nbytes = size * sizeof(PyObject *); /* Check for overflow */ if (nbytes / sizeof(PyObject *) != (size_t)size || - (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *)) - <= 0) + (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *))) { return PyErr_NoMemory(); } + nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); + op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); if (op == NULL) return NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c85a063..847b61d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -311,6 +311,11 @@ PyUnicodeObject *_PyUnicode_New(Py_ssize_t length) return unicode_empty; } + /* Ensure we won't overflow the size. */ + if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + return (PyUnicodeObject *)PyErr_NoMemory(); + } + /* Unicode freelist & memory allocation */ if (free_list) { unicode = free_list; @@ -1860,6 +1865,9 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s, if (size == 0) return PyBytes_FromStringAndSize(NULL, 0); + if (cbAllocated / 5 != size) + return PyErr_NoMemory(); + v = PyByteArray_FromStringAndSize(NULL, cbAllocated); if (v == NULL) return NULL; @@ -2452,8 +2460,9 @@ PyUnicode_EncodeUTF32(const Py_UNICODE *s, { PyObject *v, *result; unsigned char *p; + Py_ssize_t nsize, bytesize; #ifndef Py_UNICODE_WIDE - int i, pairs; + Py_ssize_t i, pairs; #else const int pairs = 0; #endif @@ -2481,8 +2490,11 @@ PyUnicode_EncodeUTF32(const Py_UNICODE *s, 0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF) pairs++; #endif - v = PyByteArray_FromStringAndSize(NULL, - 4 * (size - pairs + (byteorder == 0))); + nsize = (size - pairs + (byteorder == 0)); + bytesize = nsize * 4; + if (bytesize / 4 != nsize) + return PyErr_NoMemory(); + v = PyByteArray_FromStringAndSize(NULL, bytesize); if (v == NULL) return NULL; @@ -2726,8 +2738,9 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s, { PyObject *v, *result; unsigned char *p; + Py_ssize_t nsize, bytesize; #ifdef Py_UNICODE_WIDE - int i, pairs; + Py_ssize_t i, pairs; #else const int pairs = 0; #endif @@ -2750,8 +2763,15 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s, if (s[i] >= 0x10000) pairs++; #endif - v = PyByteArray_FromStringAndSize(NULL, - 2 * (size + pairs + (byteorder == 0))); + /* 2 * (size + pairs + (byteorder == 0)) */ + if (size > PY_SSIZE_T_MAX || + size > PY_SSIZE_T_MAX - pairs - (byteorder == 0)) + return PyErr_NoMemory(); + nsize = size + pairs + (byteorder == 0); + bytesize = nsize * 2; + if (bytesize / 2 != nsize) + return PyErr_NoMemory(); + v = PyByteArray_FromStringAndSize(NULL, bytesize); if (v == NULL) return NULL; @@ -3082,6 +3102,12 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, PyObject *repr, *result; char *p; +#ifdef Py_UNICODE_WIDE + const Py_ssize_t expandsize = 10; +#else + const Py_ssize_t expandsize = 6; +#endif + /* XXX(nnorwitz): rather than over-allocating, it would be better to choose a different scheme. Perhaps scan the first N-chars of the string and allocate based on that size. @@ -3100,12 +3126,12 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, escape. */ + if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize) + return PyErr_NoMemory(); + repr = PyByteArray_FromStringAndSize(NULL, -#ifdef Py_UNICODE_WIDE - + 10*size -#else - + 6*size -#endif + 2 + + expandsize*size + 1); if (repr == NULL) return NULL; @@ -3353,10 +3379,15 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, char *q; #ifdef Py_UNICODE_WIDE - repr = PyByteArray_FromStringAndSize(NULL, 10 * size); + const Py_ssize_t expandsize = 10; #else - repr = PyByteArray_FromStringAndSize(NULL, 6 * size); + const Py_ssize_t expandsize = 6; #endif + + if (size > PY_SSIZE_T_MAX / expandsize) + return PyErr_NoMemory(); + + repr = PyByteArray_FromStringAndSize(NULL, expandsize * size); if (repr == NULL) return NULL; if (size == 0) @@ -5747,6 +5778,11 @@ PyUnicodeObject *pad(PyUnicodeObject *self, return self; } + if (left > PY_SSIZE_T_MAX - self->length || + right > PY_SSIZE_T_MAX - (left + self->length)) { + PyErr_SetString(PyExc_OverflowError, "padded string is too long"); + return NULL; + } u = _PyUnicode_New(left + self->length + right); if (u) { if (left) |