From 1274766d3c29007ab77245a72abbf8dce2a9db4d Mon Sep 17 00:00:00 2001 From: Seth Larson Date: Tue, 21 Apr 2026 09:29:07 -0500 Subject: [PATCH] =?utf8?q?gh-148808:=20Add=20boundary=20check=20to=20async?= =?utf8?q?io.AbstractEventLoop.sock=5Frecvf=E2=80=A6=20(#148809)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Lib/test/test_asyncio/test_sock_lowlevel.py | 21 +++++++++++++++++++ ...-04-20-15-31-37.gh-issue-148808._Z8JL0.rst | 3 +++ Modules/overlapped.c | 5 +++++ 3 files changed, 29 insertions(+) create mode 100644 Misc/NEWS.d/next/Security/2026-04-20-15-31-37.gh-issue-148808._Z8JL0.rst diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py index df4ec7948975..f32dcd589e2d 100644 --- a/Lib/test/test_asyncio/test_sock_lowlevel.py +++ b/Lib/test/test_asyncio/test_sock_lowlevel.py @@ -427,6 +427,27 @@ class BaseSockTestsMixin: self.loop.run_until_complete( self._basetest_datagram_recvfrom_into(server_address)) + async def _basetest_datagram_recvfrom_into_wrong_size(self, server_address): + # Call sock_sendto() with a size larger than the buffer + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.setblocking(False) + + buf = bytearray(5000) + data = b'\x01' * 4096 + wrong_size = len(buf) + 1 + await self.loop.sock_sendto(sock, data, server_address) + with self.assertRaises(ValueError): + await self.loop.sock_recvfrom_into( + sock, buf, wrong_size) + + size, addr = await self.loop.sock_recvfrom_into(sock, buf) + self.assertEqual(buf[:size], data) + + def test_recvfrom_into_wrong_size(self): + with test_utils.run_udp_echo_server() as server_address: + self.loop.run_until_complete( + self._basetest_datagram_recvfrom_into_wrong_size(server_address)) + async def _basetest_datagram_sendto_blocking(self, server_address): # Sad path, sock.sendto() raises BlockingIOError # This involves patching sock.sendto() to raise BlockingIOError but diff --git a/Misc/NEWS.d/next/Security/2026-04-20-15-31-37.gh-issue-148808._Z8JL0.rst b/Misc/NEWS.d/next/Security/2026-04-20-15-31-37.gh-issue-148808._Z8JL0.rst new file mode 100644 index 000000000000..0b5cf85fedfb --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-04-20-15-31-37.gh-issue-148808._Z8JL0.rst @@ -0,0 +1,3 @@ +Added buffer boundary check when using ``nbytes`` parameter with +:meth:`!asyncio.AbstractEventLoop.sock_recvfrom_into`. Only +relevant for Windows and the :class:`asyncio.ProactorEventLoop`. diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 822e1ce4bdc2..51aee5afd35b 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1910,6 +1910,11 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, } #endif + if (bufobj->len < (Py_ssize_t)size) { + PyErr_SetString(PyExc_ValueError, "nbytes is greater than the length of the buffer"); + return NULL; + } + wsabuf.buf = bufobj->buf; wsabuf.len = size; -- 2.47.3