From 019df146cfbf531d86c3324c1c43502cf7b14c09 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 12 Nov 2024 19:16:55 +0100 Subject: [PATCH 1/3] gh-126594: Fix typeobject.c wrap_buffer() cast Reject flags smaller than INT_MIN. --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4af7f0273aae91..75a3461a9919f7 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9314,13 +9314,13 @@ wrap_buffer(PyObject *self, PyObject *args, void *wrapped) if (flags == -1 && PyErr_Occurred()) { return NULL; } - if (flags > INT_MAX) { + if (flags > INT_MAX || flags < INT_MIN) { PyErr_SetString(PyExc_OverflowError, "buffer flags too large"); return NULL; } - return _PyMemoryView_FromBufferProc(self, Py_SAFE_DOWNCAST(flags, Py_ssize_t, int), + return _PyMemoryView_FromBufferProc(self, (int)flags, (getbufferproc)wrapped); } From 9a6bcc7706748b6177d3851e3115bf4efa1e8a08 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Nov 2024 00:03:06 +0100 Subject: [PATCH 2/3] Update Objects/typeobject.c Co-authored-by: Jelle Zijlstra --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 75a3461a9919f7..6dc9f80c35892b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9316,7 +9316,7 @@ wrap_buffer(PyObject *self, PyObject *args, void *wrapped) } if (flags > INT_MAX || flags < INT_MIN) { PyErr_SetString(PyExc_OverflowError, - "buffer flags too large"); + "buffer flags out of range"); return NULL; } From 0351e7f966fab456df5ef4d67d34c7efa1778afe Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 18 Nov 2024 14:51:08 +0100 Subject: [PATCH 3/3] Add test --- Lib/test/test_buffer.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index cb38a69e390f3a..332e49ce9f1b17 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -4446,6 +4446,21 @@ def test_pybuffer_size_from_format(self): self.assertEqual(_testcapi.PyBuffer_SizeFromFormat(format), struct.calcsize(format)) + @support.cpython_only + def test_flags_overflow(self): + # gh-126594: Check for integer overlow on large flags + try: + from _testcapi import INT_MIN, INT_MAX + except ImportError: + INT_MIN = -(2 ** 31) + INT_MAX = 2 ** 31 - 1 + + obj = b'abc' + for flags in (INT_MIN - 1, INT_MAX + 1): + with self.subTest(flags=flags): + with self.assertRaises(OverflowError): + obj.__buffer__(flags) + class TestPythonBufferProtocol(unittest.TestCase): def test_basic(self):