mirror of https://github.com/python/cpython
Resolve issue 3321: (segfault) _multiprocessing.Connection() doesn't check handle
This commit is contained in:
parent
273c1d9a8b
commit
9a5b2ad38d
|
@ -61,6 +61,8 @@ else:
|
||||||
HAVE_GETVALUE = not getattr(_multiprocessing,
|
HAVE_GETVALUE = not getattr(_multiprocessing,
|
||||||
'HAVE_BROKEN_SEM_GETVALUE', False)
|
'HAVE_BROKEN_SEM_GETVALUE', False)
|
||||||
|
|
||||||
|
WIN32 = (sys.platform == "win32")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Creates a wrapper for a function which records the time it takes to finish
|
# Creates a wrapper for a function which records the time it takes to finish
|
||||||
#
|
#
|
||||||
|
@ -1682,6 +1684,18 @@ class _TestLogging(BaseTestCase):
|
||||||
logger.setLevel(level=LOG_LEVEL)
|
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
|
# Functions used to create test cases from the base ones in this module
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -1785,7 +1799,7 @@ class OtherTest(unittest.TestCase):
|
||||||
multiprocessing.connection.answer_challenge,
|
multiprocessing.connection.answer_challenge,
|
||||||
_FakeConnection(), b'abc')
|
_FakeConnection(), b'abc')
|
||||||
|
|
||||||
testcases_other = [OtherTest]
|
testcases_other = [OtherTest, TestInvalidHandle]
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
|
@ -140,6 +140,10 @@ Core and Builtins
|
||||||
Library
|
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
|
- Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying issue
|
||||||
in sharedctypes.py.
|
in sharedctypes.py.
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,7 @@ connection_poll(ConnectionObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
res = conn_poll(self, timeout);
|
res = conn_poll(self, timeout, _save);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
|
|
|
@ -153,11 +153,23 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
conn_poll(ConnectionObject *conn, double timeout)
|
conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
fd_set rfds;
|
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_ZERO(&rfds);
|
||||||
FD_SET((SOCKET)conn->handle, &rfds);
|
FD_SET((SOCKET)conn->handle, &rfds);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue