From 0443f926becc38480fe60529ad9049ccceb635bd Mon Sep 17 00:00:00 2001 From: Alexey Izbyshev Date: Fri, 1 Dec 2023 18:44:03 +0300 Subject: [3.11] bpo-35191: Fix unexpected integer truncation in socket.setblocking() (GH-10415) On platforms with 64-bit long, socket.setblocking(x) treated all x which lower 32 bits are zero as False due to integer truncation. Reported by ubsan. --- Lib/test/test_socket.py | 4 ++-- Misc/NEWS.d/next/Library/2018-11-08-18-44-04.bpo-35191.s29bWu.rst | 2 ++ Modules/socketmodule.c | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-11-08-18-44-04.bpo-35191.s29bWu.rst diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 3fceac3..f6941e7 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4705,10 +4705,10 @@ class NonBlockingTCPTests(ThreadedTCPSocketTest): self.skipTest('needs UINT_MAX < ULONG_MAX') self.serv.setblocking(False) - self.assertEqual(self.serv.gettimeout(), 0.0) + self.assert_sock_timeout(self.serv, 0.0) self.serv.setblocking(_testcapi.UINT_MAX + 1) - self.assertIsNone(self.serv.gettimeout()) + self.assert_sock_timeout(self.serv, None) _testSetBlocking_overflow = support.cpython_only(_testSetBlocking) diff --git a/Misc/NEWS.d/next/Library/2018-11-08-18-44-04.bpo-35191.s29bWu.rst b/Misc/NEWS.d/next/Library/2018-11-08-18-44-04.bpo-35191.s29bWu.rst new file mode 100644 index 0000000..37f6f56 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-08-18-44-04.bpo-35191.s29bWu.rst @@ -0,0 +1,2 @@ +Fix unexpected integer truncation in :meth:`socket.setblocking` which caused +it to interpret multiples of ``2**32`` as ``False``. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 8d9d3c3..997df43 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2815,12 +2815,14 @@ For IP sockets, the address info is a pair (hostaddr, port)."); static PyObject * sock_setblocking(PySocketSockObject *s, PyObject *arg) { - long block; + long value; + int block; - block = PyLong_AsLong(arg); - if (block == -1 && PyErr_Occurred()) + value = PyLong_AsLong(arg); + if (value == -1 && PyErr_Occurred()) return NULL; + block = (value != 0); s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); if (internal_setblocking(s, block) == -1) { return NULL; -- cgit v0.12