From e76bc8d64f1351fbcc4deee255c135902e8179de500c09155a97169ce8a2016e Mon Sep 17 00:00:00 2001 From: Jan Matejek Date: Thu, 5 Jan 2017 11:54:43 +0000 Subject: [PATCH] - update python-2.7.10-overflow_check.patch with python-2.7.13-overflow_check.patch, incorporating upstream changes OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python?expand=0&rev=201 --- python-2.7.13-overflow_check.patch | 300 +++++++++++++++++++++++++++++ python-base.changes | 5 +- python-base.spec | 5 +- python-doc.spec | 2 + python.changes | 5 +- python.spec | 4 +- 6 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 python-2.7.13-overflow_check.patch diff --git a/python-2.7.13-overflow_check.patch b/python-2.7.13-overflow_check.patch new file mode 100644 index 0000000..8a70afb --- /dev/null +++ b/python-2.7.13-overflow_check.patch @@ -0,0 +1,300 @@ +Index: Python-2.7.13/Objects/unicodeobject.c +=================================================================== +--- Python-2.7.13.orig/Objects/unicodeobject.c ++++ Python-2.7.13/Objects/unicodeobject.c +@@ -5732,20 +5732,20 @@ PyUnicode_Join(PyObject *separator, PyOb + + /* Make sure we have enough space for the separator and the item. */ + itemlen = PyUnicode_GET_SIZE(item); +- new_res_used = res_used + itemlen; +- if (new_res_used < 0) ++ if (res_used > PY_SSIZE_T_MAX - itemlen) + goto Overflow; ++ new_res_used = res_used + itemlen; + if (i < seqlen - 1) { +- new_res_used += seplen; +- if (new_res_used < 0) ++ if (new_res_used > PY_SSIZE_T_MAX - seplen) + goto Overflow; ++ new_res_used += seplen; + } + if (new_res_used > res_alloc) { + /* double allocated size until it's big enough */ + do { +- res_alloc += res_alloc; +- if (res_alloc <= 0) ++ if (res_alloc >= PY_SSIZE_T_MAX - res_alloc) + goto Overflow; ++ res_alloc += res_alloc; + } while (new_res_used > res_alloc); + if (_PyUnicode_Resize(&res, res_alloc) < 0) { + Py_DECREF(item); +@@ -5943,7 +5943,7 @@ PyObject *replace(PyUnicodeObject *self, + } else { + + Py_ssize_t n, i, j; +- Py_ssize_t product, new_size, delta; ++ Py_ssize_t new_size, delta; + Py_UNICODE *p; + + /* replace strings */ +@@ -5956,18 +5956,12 @@ PyObject *replace(PyUnicodeObject *self, + if (delta == 0) { + new_size = self->length; + } else { +- product = n * (str2->length - str1->length); +- if ((product / (str2->length - str1->length)) != n) { +- PyErr_SetString(PyExc_OverflowError, +- "replace string is too long"); +- return NULL; +- } +- new_size = self->length + product; +- if (new_size < 0) { ++ if (str2->length - str1->length > (PY_SSIZE_T_MAX - self->length) / n) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + return NULL; + } ++ new_size = self->length + n * (str2->length - str1->length); + } + u = _PyUnicode_New(new_size); + if (!u) +Index: Python-2.7.13/Objects/tupleobject.c +=================================================================== +--- Python-2.7.13.orig/Objects/tupleobject.c ++++ Python-2.7.13/Objects/tupleobject.c +@@ -446,9 +446,9 @@ tupleconcat(register PyTupleObject *a, r + return NULL; + } + #define b ((PyTupleObject *)bb) +- size = Py_SIZE(a) + Py_SIZE(b); +- if (size < 0) ++ if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) + return PyErr_NoMemory(); ++ size = Py_SIZE(a) + Py_SIZE(b); + np = (PyTupleObject *) PyTuple_New(size); + if (np == NULL) { + return NULL; +@@ -490,9 +490,9 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t + if (Py_SIZE(a) == 0) + return PyTuple_New(0); + } +- size = Py_SIZE(a) * n; +- if (size/Py_SIZE(a) != n) ++ if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) + return PyErr_NoMemory(); ++ size = Py_SIZE(a) * n; + np = (PyTupleObject *) PyTuple_New(size); + if (np == NULL) + return NULL; +diff -r 5ea0fef6ec53 Objects/bytearrayobject.c +--- a/Objects/bytearrayobject.c Wed Dec 28 15:41:09 2016 -0800 ++++ b/Objects/bytearrayobject.c Thu Jan 05 14:05:29 2017 +0800 +@@ -1571,31 +1571,30 @@ + { + char *self_s, *result_s; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, i, product; ++ Py_ssize_t count, i; + PyByteArrayObject *result; + + self_len = PyByteArray_GET_SIZE(self); + +- /* 1 at the end plus 1 after every character */ +- count = self_len+1; +- if (maxcount < count) ++ /* 1 at the end plus 1 after every character; ++ count = min(maxcount, self_len + 1) */ ++ if (maxcount <= self_len) { + count = maxcount; ++ } ++ else { ++ /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */ ++ count = self_len + 1; ++ } + + /* Check for overflow */ + /* result_len = count * to_len + self_len; */ +- product = count * to_len; +- if (product / to_len != count) { ++ assert(count > 0); ++ if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, +- "replace string is too long"); ++ "replace bytes is too long"); + return NULL; + } +- result_len = product + self_len; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, +- "replace string is too long"); +- return NULL; +- } +- ++ result_len = count * to_len + self_len; + if (! (result = (PyByteArrayObject *) + PyByteArray_FromStringAndSize(NULL, result_len)) ) + return NULL; +@@ -1824,7 +1823,7 @@ + char *self_s, *result_s; + char *start, *next, *end; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, product; ++ Py_ssize_t count; + PyByteArrayObject *result; + + self_s = PyByteArray_AS_STRING(self); +@@ -1838,16 +1837,12 @@ + + /* use the difference between current and new, hence the "-1" */ + /* result_len = self_len + count * (to_len-1) */ +- product = count * (to_len-1); +- if (product / (to_len-1) != count) { ++ assert(count > 0); ++ if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } +- result_len = self_len + product; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); +- return NULL; +- } ++ result_len = self_len + count * (to_len - 1); + + if ( (result = (PyByteArrayObject *) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) +@@ -1891,7 +1886,7 @@ + char *self_s, *result_s; + char *start, *next, *end; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, offset, product; ++ Py_ssize_t count, offset; + PyByteArrayObject *result; + + self_s = PyByteArray_AS_STRING(self); +@@ -1908,16 +1903,12 @@ + + /* Check for overflow */ + /* result_len = self_len + count * (to_len-from_len) */ +- product = count * (to_len-from_len); +- if (product / (to_len-from_len) != count) { ++ assert(count > 0); ++ if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); + return NULL; + } +- result_len = self_len + product; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); +- return NULL; +- } ++ result_len = self_len + count * (to_len - from_len); + + if ( (result = (PyByteArrayObject *) + PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) +diff -r 5ea0fef6ec53 Objects/stringobject.c +--- a/Objects/stringobject.c Wed Dec 28 15:41:09 2016 -0800 ++++ b/Objects/stringobject.c Thu Jan 05 14:05:29 2017 +0800 +@@ -2358,31 +2358,30 @@ + { + char *self_s, *result_s; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, i, product; ++ Py_ssize_t count, i; + PyStringObject *result; + + self_len = PyString_GET_SIZE(self); + +- /* 1 at the end plus 1 after every character */ +- count = self_len+1; +- if (maxcount < count) ++ /* 1 at the end plus 1 after every character; ++ count = min(maxcount, self_len + 1) */ ++ if (maxcount <= self_len) { + count = maxcount; ++ } ++ else { ++ /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */ ++ count = self_len + 1; ++ } + + /* Check for overflow */ + /* result_len = count * to_len + self_len; */ +- product = count * to_len; +- if (product / to_len != count) { ++ assert(count > 0); ++ if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, + "replace string is too long"); + return NULL; + } +- result_len = product + self_len; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, +- "replace string is too long"); +- return NULL; +- } +- ++ result_len = count * to_len + self_len; + if (! (result = (PyStringObject *) + PyString_FromStringAndSize(NULL, result_len)) ) + return NULL; +@@ -2610,7 +2609,7 @@ + char *self_s, *result_s; + char *start, *next, *end; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, product; ++ Py_ssize_t count; + PyStringObject *result; + + self_s = PyString_AS_STRING(self); +@@ -2624,16 +2623,12 @@ + + /* use the difference between current and new, hence the "-1" */ + /* result_len = self_len + count * (to_len-1) */ +- product = count * (to_len-1); +- if (product / (to_len-1) != count) { ++ assert(count > 0); ++ if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } +- result_len = self_len + product; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, "replace string is too long"); +- return NULL; +- } ++ result_len = self_len + count * (to_len - 1); + + if ( (result = (PyStringObject *) + PyString_FromStringAndSize(NULL, result_len)) == NULL) +@@ -2676,7 +2671,7 @@ + char *self_s, *result_s; + char *start, *next, *end; + Py_ssize_t self_len, result_len; +- Py_ssize_t count, offset, product; ++ Py_ssize_t count, offset; + PyStringObject *result; + + self_s = PyString_AS_STRING(self); +@@ -2693,16 +2688,12 @@ + + /* Check for overflow */ + /* result_len = self_len + count * (to_len-from_len) */ +- product = count * (to_len-from_len); +- if (product / (to_len-from_len) != count) { ++ assert(count > 0); ++ if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { + PyErr_SetString(PyExc_OverflowError, "replace string is too long"); + return NULL; + } +- result_len = self_len + product; +- if (result_len < 0) { +- PyErr_SetString(PyExc_OverflowError, "replace string is too long"); +- return NULL; +- } ++ result_len = self_len + count * (to_len - from_len); + + if ( (result = (PyStringObject *) + PyString_FromStringAndSize(NULL, result_len)) == NULL) diff --git a/python-base.changes b/python-base.changes index 229d576..2198a57 100644 --- a/python-base.changes +++ b/python-base.changes @@ -6,7 +6,10 @@ Tue Jan 3 16:59:24 UTC 2017 - jmatejek@suse.com * updated cipher lists for openssl wrapper, support openssl >= 1.1.0 * properly fix HTTPoxy (CVE-2016-1000110) * profile-opt build now applies PGO to modules as well -- drop python-2.7.10-overflow_check.patch which is solved in upstream +- update python-2.7.10-overflow_check.patch + with python-2.7.13-overflow_check.patch, incorporating upstream changes +- add "-fwrapv" to optflags explicitly because upstream code still + relies on it in many places ------------------------------------------------------------------- Fri Dec 2 15:32:59 UTC 2016 - jmatejek@suse.com diff --git a/python-base.spec b/python-base.spec index 57ea132..0d0592f 100644 --- a/python-base.spec +++ b/python-base.spec @@ -54,6 +54,7 @@ Patch33: python-2.7.9-ssl_ca_path.patch Patch34: python-2.7.9-sles-disable-verification-by-default.patch # PATCH-FIX-UPSTREAM python-ncurses-6.0-accessors.patch dimstar@opensuse.org -- Fix build with NCurses 6.0 and OPAQUE_WINDOW set to 1 Patch35: python-ncurses-6.0-accessors.patch +Patch36: python-2.7.13-overflow_check.patch Patch37: python-2.7.12-makeopcode.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) @@ -63,6 +64,7 @@ BuildRequires: libbz2-devel BuildRequires: pkg-config BuildRequires: xz BuildRequires: zlib-devel +#!BuildIgnore: python # for the test suite BuildRequires: netcfg Requires: python-rpm-macros @@ -152,6 +154,7 @@ other applications. %patch34 -p1 %endif %patch35 -p1 +%patch36 -p1 %patch37 -p1 # drop Autoconf version requirement @@ -159,7 +162,7 @@ sed -i 's/^version_required/dnl version_required/' configure.ac # COMMON-PREP-END %build -export OPT="%{optflags} -DOPENSSL_LOAD_CONF" +export OPT="%{optflags} -DOPENSSL_LOAD_CONF -fwrapv" autoreconf -f -i . # Modules/_ctypes/libffi diff --git a/python-doc.spec b/python-doc.spec index 3f8b6cf..17cb804 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -55,6 +55,7 @@ Patch33: python-2.7.9-ssl_ca_path.patch Patch34: python-2.7.9-sles-disable-verification-by-default.patch # PATCH-FIX-UPSTREAM python-ncurses-6.0-accessors.patch dimstar@opensuse.org -- Fix build with NCurses 6.0 and OPAQUE_WINDOW set to 1 Patch35: python-ncurses-6.0-accessors.patch +Patch36: python-2.7.13-overflow_check.patch Patch37: python-2.7.12-makeopcode.patch # COMMON-PATCH-END Provides: pyth_doc @@ -104,6 +105,7 @@ Python, and Macintosh Module Reference in PDF format. %patch34 -p1 %endif %patch35 -p1 +%patch36 -p1 %patch37 -p1 # drop Autoconf version requirement diff --git a/python.changes b/python.changes index 1e319a9..589051d 100644 --- a/python.changes +++ b/python.changes @@ -6,7 +6,10 @@ Tue Jan 3 16:59:24 UTC 2017 - jmatejek@suse.com * updated cipher lists for openssl wrapper, support openssl >= 1.1.0 * properly fix HTTPoxy (CVE-2016-1000110) * profile-opt build now applies PGO to modules as well -- drop python-2.7.10-overflow_check.patch which is solved in upstream +- update python-2.7.10-overflow_check.patch + with python-2.7.13-overflow_check.patch, incorporating upstream changes +- add "-fwrapv" to optflags explicitly because upstream code still + relies on it in many places ------------------------------------------------------------------- Fri Dec 2 15:35:29 UTC 2016 - jmatejek@suse.com diff --git a/python.spec b/python.spec index cca9cec..1c590bf 100644 --- a/python.spec +++ b/python.spec @@ -60,6 +60,7 @@ Patch33: python-2.7.9-ssl_ca_path.patch Patch34: python-2.7.9-sles-disable-verification-by-default.patch # PATCH-FIX-UPSTREAM python-ncurses-6.0-accessors.patch dimstar@opensuse.org -- Fix build with NCurses 6.0 and OPAQUE_WINDOW set to 1 Patch35: python-ncurses-6.0-accessors.patch +Patch36: python-2.7.13-overflow_check.patch Patch37: python-2.7.12-makeopcode.patch # COMMON-PATCH-END BuildRequires: automake @@ -209,6 +210,7 @@ that rely on earlier non-verification behavior. %patch34 -p1 %endif %patch35 -p1 +%patch36 -p1 %patch37 -p1 # drop Autoconf version requirement @@ -223,7 +225,7 @@ cp %{SOURCE8} Lib/ # necessary for correct linking with GDBM: export SUSE_ASNEEDED=0 -export OPT="%{optflags} -DOPENSSL_LOAD_CONF" +export OPT="%{optflags} -DOPENSSL_LOAD_CONF -fwrapv" autoreconf -f -i . # Modules/_ctypes/libffi # prevent make from trying to rebuild asdl stuff, which requires existing