From 82b92e3cd180723a354cdeb0f0f1d593f1b5eb0d Mon Sep 17 00:00:00 2001 From: Priyanshu Singh Date: Fri, 13 Feb 2026 21:05:08 +0530 Subject: [PATCH 1/2] gh-143637: Fix re-entrant mutation of ancillary data in socket.sendmsg() (#143892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Victor Stinner Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Lib/test/test_socket.py | 18 ++++++++++++++++++ ...6-01-17-08-44-25.gh-issue-143637.qyPqDo.rst | 1 + Modules/socketmodule.c | 13 ++++++++----- 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 934b7137096bc0..3806ad988db214 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2222,6 +2222,24 @@ def test_addressinfo_enum(self): source=_socket) enum._test_simple_enum(CheckedAddressInfo, socket.AddressInfo) + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"),"sendmsg not supported") + def test_sendmsg_reentrant_ancillary_mutation(self): + + class Mut: + def __index__(self): + seq.clear() + return 0 + + seq = [ + (socket.SOL_SOCKET, Mut(), b'x'), + (socket.SOL_SOCKET, 0, b'x'), + ] + + left, right = socket.socketpair() + self.addCleanup(left.close) + self.addCleanup(right.close) + self.assertRaises(OSError, left.sendmsg, [b'x'], seq) + @unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') class BasicCANTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst new file mode 100644 index 00000000000000..cbb21194d5b387 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst @@ -0,0 +1 @@ +Fixed a crash in socket.sendmsg() that could occur if ancillary data is mutated re-entrantly during argument parsing. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ee78ad01598262..d4df40c78e8a4f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4983,11 +4983,13 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, if (cmsg_arg == NULL) ncmsgs = 0; else { - if ((cmsg_fast = PySequence_Fast(cmsg_arg, - "sendmsg() argument 2 must be an " - "iterable")) == NULL) + cmsg_fast = PySequence_Tuple(cmsg_arg); + if (cmsg_fast == NULL) { + PyErr_SetString(PyExc_TypeError, + "sendmsg() argument 2 must be an iterable"); goto finally; - ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast); + } + ncmsgs = PyTuple_GET_SIZE(cmsg_fast); } #ifndef CMSG_SPACE @@ -5007,8 +5009,9 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, controllen = controllen_last = 0; while (ncmsgbufs < ncmsgs) { size_t bufsize, space; + PyObject *item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), + if (!PyArg_Parse(item, "(iiy*):[sendmsg() ancillary data items]", &cmsgs[ncmsgbufs].level, &cmsgs[ncmsgbufs].type, From d625f7da33bf8eb57fb7e1a05deae3f68bf4d00f Mon Sep 17 00:00:00 2001 From: Colin McAllister Date: Fri, 13 Feb 2026 11:17:53 -0600 Subject: [PATCH 2/2] gh-144787: [tests] Allow TLS v1.2 to be minimum version (GH-144790) Allow TLS v1.2 to be minimum version Updates test_min_max_version to allow TLS v1.2 to be minimum version if TLS 1.0 and 1.1 are disabled in OpenSSL. --- Lib/test/test_ssl.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6023c89bca03f9..7e9ba735b3ce66 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1156,7 +1156,12 @@ def test_min_max_version(self): ctx.maximum_version = ssl.TLSVersion.MINIMUM_SUPPORTED self.assertIn( ctx.maximum_version, - {ssl.TLSVersion.TLSv1, ssl.TLSVersion.TLSv1_1, ssl.TLSVersion.SSLv3} + { + ssl.TLSVersion.TLSv1, + ssl.TLSVersion.TLSv1_1, + ssl.TLSVersion.TLSv1_2, + ssl.TLSVersion.SSLv3, + } ) ctx.minimum_version = ssl.TLSVersion.MAXIMUM_SUPPORTED