From 166d7d1d314a1d93f958fd5694378e949f41c1b7 Mon Sep 17 00:00:00 2001 From: Anssi Hannula <anssi.hannula@iki.fi> Date: Sat, 13 Nov 2010 08:48:00 +0200 Subject: [PATCH 10/15] fixed: CVE-2008-5031 in internal python (upstream) --- xbmc/lib/libPython/Python/Objects/stringobject.c | 44 ++++++++++++++++----- xbmc/lib/libPython/Python/Objects/unicodeobject.c | 43 ++++++++++++++++---- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/xbmc/lib/libPython/Python/Objects/stringobject.c b/xbmc/lib/libPython/Python/Objects/stringobject.c index 374111b..b4ba9eb 100644 --- a/xbmc/lib/libPython/Python/Objects/stringobject.c +++ b/xbmc/lib/libPython/Python/Objects/stringobject.c @@ -2757,9 +2757,9 @@ If tabsize is not given, a tab size of 8 characters is assumed."); static PyObject* string_expandtabs(PyStringObject *self, PyObject *args) { - const char *e, *p; + const char *e, *p, *qe; char *q; - int i, j; + int i, j, incr; PyObject *u; int tabsize = 8; @@ -2767,46 +2767,70 @@ string_expandtabs(PyStringObject *self, PyObject *args) return NULL; /* First pass: determine size of output string */ - i = j = 0; - e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); + i = 0; /* chars up to and including most recent \n or \r */ + j = 0; /* chars since most recent \n or \r (use in tab calculations) */ + e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); /* end of input */ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { - if (tabsize > 0) - j += tabsize - (j % tabsize); + if (tabsize > 0) { + incr = tabsize - (j % tabsize); + if (j > INT_MAX - incr) + goto overflow1; + j += incr; + } } else { + if (j > INT_MAX - 1) + goto overflow1; j++; if (*p == '\n' || *p == '\r') { + if (i > INT_MAX - j) + goto overflow1; i += j; j = 0; } } + if (i > INT_MAX - j) + goto overflow1; + /* Second pass: create output string and fill it */ u = PyString_FromStringAndSize(NULL, i + j); if (!u) return NULL; - j = 0; - q = PyString_AS_STRING(u); + j = 0; /* same as in first pass */ + q = PyString_AS_STRING(u); /* next output char */ + qe = PyString_AS_STRING(u) + PyString_GET_SIZE(u); /* end of output */ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); j += i; - while (i--) + while (i--) { + if (q >= qe) + goto overflow2; *q++ = ' '; + } } } else { - j++; + if (q >= qe) + goto overflow2; *q++ = *p; + j++; if (*p == '\n' || *p == '\r') j = 0; } return u; + + overflow2: + Py_DECREF(u); + overflow1: + PyErr_SetString(PyExc_OverflowError, "new string is too long"); + return NULL; } static PyObject * diff --git a/xbmc/lib/libPython/Python/Objects/unicodeobject.c b/xbmc/lib/libPython/Python/Objects/unicodeobject.c index de3aada..0547f00 100644 --- a/xbmc/lib/libPython/Python/Objects/unicodeobject.c +++ b/xbmc/lib/libPython/Python/Objects/unicodeobject.c @@ -5207,7 +5207,8 @@ unicode_expandtabs(PyUnicodeObject *self, PyObject *args) Py_UNICODE *e; Py_UNICODE *p; Py_UNICODE *q; - int i, j; + Py_UNICODE *qe; + int i, j, incr; PyUnicodeObject *u; int tabsize = 8; @@ -5215,46 +5216,70 @@ unicode_expandtabs(PyUnicodeObject *self, PyObject *args) return NULL; /* First pass: determine size of output string */ - i = j = 0; - e = self->str + self->length; + i = 0; /* chars up to and including most recent \n or \r */ + j = 0; /* chars since most recent \n or \r (use in tab calculations) */ + e = self->str + self->length; /* end of input */ for (p = self->str; p < e; p++) if (*p == '\t') { - if (tabsize > 0) - j += tabsize - (j % tabsize); + if (tabsize > 0) { + incr = tabsize - (j % tabsize); /* cannot overflow */ + if (j > INT_MAX - incr) + goto overflow1; + j += incr; + } } else { + if (j > INT_MAX - 1) + goto overflow1; j++; if (*p == '\n' || *p == '\r') { + if (i > INT_MAX - j) + goto overflow1; i += j; j = 0; } } + if (i > INT_MAX - j) + goto overflow1; + /* Second pass: create output string and fill it */ u = _PyUnicode_New(i + j); if (!u) return NULL; - j = 0; - q = u->str; + j = 0; /* same as in first pass */ + q = u->str; /* next output char */ + qe = u->str + u->length; /* end of output */ for (p = self->str; p < e; p++) if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); j += i; - while (i--) + while (i--) { + if (q >= qe) + goto overflow2; *q++ = ' '; + } } } else { - j++; + if (q >= qe) + goto overflow2; *q++ = *p; + j++; if (*p == '\n' || *p == '\r') j = 0; } return (PyObject*) u; + + overflow2: + Py_DECREF(u); + overflow1: + PyErr_SetString(PyExc_OverflowError, "new string is too long"); + return NULL; } PyDoc_STRVAR(find__doc__, -- 1.7.3