diff --git a/Misc/NEWS.d/next/C_API/2026-07-14-12-54-20.gh-issue-153689.abcdef.rst b/Misc/NEWS.d/next/C_API/2026-07-14-12-54-20.gh-issue-153689.abcdef.rst new file mode 100644 index 000000000000000..6818b45c8dec4bc --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-07-14-12-54-20.gh-issue-153689.abcdef.rst @@ -0,0 +1 @@ +Fix potential integer overflows in PyObject_CopyData when processing multi-dimensional buffers with exceptionally large dimensions or shapes. diff --git a/Objects/abstract.c b/Objects/abstract.c index 28f751965f36b94..344a861f9178849 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -718,7 +718,12 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) /* Otherwise a more elaborate copy scheme is needed */ - /* XXX(nnorwitz): need to check for overflow! */ + if ((size_t)view_src.ndim > (size_t)PyBUF_MAX_NDIM) { + PyErr_SetString(PyExc_BufferError, "invalid ndim"); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); + return -1; + } indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim); if (indices == NULL) { PyErr_NoMemory(); @@ -731,7 +736,13 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) } elements = 1; for (k=0; k PY_SSIZE_T_MAX / view_src.shape[k]) { + PyMem_Free(indices); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); + PyErr_SetString(PyExc_BufferError, "buffer is too large"); + return -1; + } elements *= view_src.shape[k]; } while (elements--) {