Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 68762) +++ Misc/NEWS (working copy) @@ -140,6 +140,10 @@ Library ------- +- Issue #3321: _multiprocessing.Connection() doesn't check handle; added checks + for *nix machines for negative handles and large int handles. Without this check + it is possible to segfault the interpreter. + - Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying issue in sharedctypes.py. Index: Lib/test/test_multiprocessing.py =================================================================== --- Lib/test/test_multiprocessing.py (revision 68762) +++ Lib/test/test_multiprocessing.py (working copy) @@ -61,6 +61,8 @@ HAVE_GETVALUE = not getattr(_multiprocessing, 'HAVE_BROKEN_SEM_GETVALUE', False) +WIN32 = (sys.platform == "win32") + # # Creates a wrapper for a function which records the time it takes to finish # @@ -1682,6 +1684,18 @@ logger.setLevel(level=LOG_LEVEL) # +# Test to verify handle verification, see issue 3321 +# + +class TestInvalidHandle(unittest.TestCase): + + def test_invalid_handles(self): + if WIN32: + return + conn = _multiprocessing.Connection(44977608) + self.assertRaises(IOError, conn.poll) + self.assertRaises(IOError, _multiprocessing.Connection, -1) +# # Functions used to create test cases from the base ones in this module # @@ -1785,7 +1799,7 @@ multiprocessing.connection.answer_challenge, _FakeConnection(), b'abc') -testcases_other = [OtherTest] +testcases_other = [OtherTest, TestInvalidHandle] # # Index: Modules/_multiprocessing/connection.h =================================================================== --- Modules/_multiprocessing/connection.h (revision 68762) +++ Modules/_multiprocessing/connection.h (working copy) @@ -354,7 +354,7 @@ } Py_BEGIN_ALLOW_THREADS - res = conn_poll(self, timeout); + res = conn_poll(self, timeout, _save); Py_END_ALLOW_THREADS switch (res) { Index: Modules/_multiprocessing/socket_connection.c =================================================================== --- Modules/_multiprocessing/socket_connection.c (revision 68762) +++ Modules/_multiprocessing/socket_connection.c (working copy) @@ -153,11 +153,23 @@ */ static int -conn_poll(ConnectionObject *conn, double timeout) +conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save) { int res; fd_set rfds; + /* + * Verify the handle, issue 3321. Not required for windows. + */ + #ifndef MS_WINDOWS + if (((int)conn->handle) < 0 || ((int)conn->handle) >= FD_SETSIZE) { + Py_BLOCK_THREADS + PyErr_SetString(PyExc_IOError, "handle out of range in select()"); + Py_UNBLOCK_THREADS + return MP_EXCEPTION_HAS_BEEN_SET; + } + #endif + FD_ZERO(&rfds); FD_SET((SOCKET)conn->handle, &rfds);