Skip to content

Commit dbbd6d2

Browse files
author
jesse.noller
committed
Resolve issue 3321: (segfault) _multiprocessing.Connection() doesn't check handle
git-svn-id: http://svn.python.org/projects/python/trunk@68768 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 9cdd190 commit dbbd6d2

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

Lib/test/test_multiprocessing.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
HAVE_GETVALUE = not getattr(_multiprocessing,
6262
'HAVE_BROKEN_SEM_GETVALUE', False)
6363

64+
WIN32 = (sys.platform == "win32")
65+
6466
#
6567
# Creates a wrapper for a function which records the time it takes to finish
6668
#
@@ -1682,6 +1684,18 @@ def test_level(self):
16821684
logger.setLevel(level=LOG_LEVEL)
16831685

16841686
#
1687+
# Test to verify handle verification, see issue 3321
1688+
#
1689+
1690+
class TestInvalidHandle(unittest.TestCase):
1691+
1692+
def test_invalid_handles(self):
1693+
if WIN32:
1694+
return
1695+
conn = _multiprocessing.Connection(44977608)
1696+
self.assertRaises(IOError, conn.poll)
1697+
self.assertRaises(IOError, _multiprocessing.Connection, -1)
1698+
#
16851699
# Functions used to create test cases from the base ones in this module
16861700
#
16871701

@@ -1785,7 +1799,7 @@ def send_bytes(self, data):
17851799
multiprocessing.connection.answer_challenge,
17861800
_FakeConnection(), b'abc')
17871801

1788-
testcases_other = [OtherTest]
1802+
testcases_other = [OtherTest, TestInvalidHandle]
17891803

17901804
#
17911805
#

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ Core and Builtins
140140
Library
141141
-------
142142

143+
- Issue #3321: _multiprocessing.Connection() doesn't check handle; added checks
144+
for *nix machines for negative handles and large int handles. Without this check
145+
it is possible to segfault the interpreter.
146+
143147
- Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying issue
144148
in sharedctypes.py.
145149

Modules/_multiprocessing/connection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ connection_poll(ConnectionObject *self, PyObject *args)
354354
}
355355

356356
Py_BEGIN_ALLOW_THREADS
357-
res = conn_poll(self, timeout);
357+
res = conn_poll(self, timeout, _save);
358358
Py_END_ALLOW_THREADS
359359

360360
switch (res) {

Modules/_multiprocessing/socket_connection.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,23 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
153153
*/
154154

155155
static int
156-
conn_poll(ConnectionObject *conn, double timeout)
156+
conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
157157
{
158158
int res;
159159
fd_set rfds;
160160

161+
/*
162+
* Verify the handle, issue 3321. Not required for windows.
163+
*/
164+
#ifndef MS_WINDOWS
165+
if (((int)conn->handle) < 0 || ((int)conn->handle) >= FD_SETSIZE) {
166+
Py_BLOCK_THREADS
167+
PyErr_SetString(PyExc_IOError, "handle out of range in select()");
168+
Py_UNBLOCK_THREADS
169+
return MP_EXCEPTION_HAS_BEEN_SET;
170+
}
171+
#endif
172+
161173
FD_ZERO(&rfds);
162174
FD_SET((SOCKET)conn->handle, &rfds);
163175

0 commit comments

Comments
 (0)