Merge in release25-maint r60793:
Added checks for integer overflows, contributed by Google. Some are
only available if asserts are left in the code, in cases where they
can't be triggered from Python code.
diff --git a/Objects/listobject.c b/Objects/listobject.c
index e72f81f..16a2ce6 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -45,7 +45,16 @@
* system realloc().
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
*/
- new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
+ new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
+
+ /* check for integer overflow */
+ if (new_allocated > PY_SIZE_MAX - newsize) {
+ PyErr_NoMemory();
+ return -1;
+ } else {
+ new_allocated += newsize;
+ }
+
if (newsize == 0)
new_allocated = 0;
items = self->ob_item;
@@ -118,8 +127,9 @@
return NULL;
}
nbytes = size * sizeof(PyObject *);
- /* Check for overflow */
- if (nbytes / sizeof(PyObject *) != (size_t)size)
+ /* Check for overflow without an actual overflow,
+ * which can cause compiler to optimise out */
+ if (size > PY_SIZE_MAX / sizeof(PyObject *))
return PyErr_NoMemory();
if (numfree) {
numfree--;
@@ -1407,6 +1417,10 @@
* we don't care what's in the block.
*/
merge_freemem(ms);
+ if (need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+ PyErr_NoMemory();
+ return -1;
+ }
ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
if (ms->a) {
ms->alloced = need;
@@ -2589,6 +2603,8 @@
step = -step;
}
+ assert(slicelength <= PY_SIZE_MAX / sizeof(PyObject*));
+
garbage = (PyObject**)
PyMem_MALLOC(slicelength*sizeof(PyObject*));
if (!garbage) {