summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2008-08-24 07:08:55 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2008-08-24 07:08:55 (GMT)
commit3ce5d9207e66d61d4b0502cf47ed2d2bcdd2212f (patch)
treec29add3a6b61f321009d73a91464f45b5d10862a /Objects
parent06db799a53cba0396908d291bbe4bcc6c1c50daa (diff)
downloadcpython-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.c5
-rw-r--r--Objects/bytesobject.c8
-rw-r--r--Objects/longobject.c2
-rw-r--r--Objects/tupleobject.c5
-rw-r--r--Objects/unicodeobject.c62
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)