Skip to content

Commit c227ab5

Browse files
author
jesse.noller
committed
Submit fix for issue3393: Memory corruption in multiprocessing module
git-svn-id: http://svn.python.org/projects/python/trunk@65376 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent b46d628 commit c227ab5

3 files changed

Lines changed: 28 additions & 19 deletions

File tree

Modules/_multiprocessing/connection.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,7 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
129129
}
130130
}
131131

132-
Py_BEGIN_ALLOW_THREADS
133132
res = conn_send_string(self, buffer + offset, size);
134-
Py_END_ALLOW_THREADS
135133

136134
if (res < 0)
137135
return mp_SetError(PyExc_IOError, res);
@@ -156,10 +154,8 @@ connection_recvbytes(ConnectionObject *self, PyObject *args)
156154
return NULL;
157155
}
158156

159-
Py_BEGIN_ALLOW_THREADS
160157
res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE,
161158
&freeme, maxlength);
162-
Py_END_ALLOW_THREADS
163159

164160
if (res < 0) {
165161
if (res == MP_BAD_MESSAGE_LENGTH) {
@@ -208,10 +204,8 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
208204
return NULL;
209205
}
210206

211-
Py_BEGIN_ALLOW_THREADS
212207
res = conn_recv_string(self, buffer+offset, length-offset,
213208
&freeme, PY_SSIZE_T_MAX);
214-
Py_END_ALLOW_THREADS
215209

216210
if (res < 0) {
217211
if (res == MP_BAD_MESSAGE_LENGTH) {
@@ -266,9 +260,7 @@ connection_send_obj(ConnectionObject *self, PyObject *obj)
266260
if (PyString_AsStringAndSize(pickled_string, &buffer, &length) < 0)
267261
goto failure;
268262

269-
Py_BEGIN_ALLOW_THREADS
270263
res = conn_send_string(self, buffer, (int)length);
271-
Py_END_ALLOW_THREADS
272264

273265
if (res < 0) {
274266
mp_SetError(PyExc_IOError, res);
@@ -292,10 +284,8 @@ connection_recv_obj(ConnectionObject *self)
292284

293285
CHECK_READABLE(self);
294286

295-
Py_BEGIN_ALLOW_THREADS
296287
res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE,
297288
&freeme, PY_SSIZE_T_MAX);
298-
Py_END_ALLOW_THREADS
299289

300290
if (res < 0) {
301291
if (res == MP_BAD_MESSAGE_LENGTH) {

Modules/_multiprocessing/pipe_connection.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ static Py_ssize_t
1818
conn_send_string(ConnectionObject *conn, char *string, size_t length)
1919
{
2020
DWORD amount_written;
21+
BOOL ret;
2122

22-
return WriteFile(conn->handle, string, length, &amount_written, NULL)
23-
? MP_SUCCESS : MP_STANDARD_ERROR;
23+
Py_BEGIN_ALLOW_THREADS
24+
ret = WriteFile(conn->handle, string, length, &amount_written, NULL);
25+
Py_END_ALLOW_THREADS
26+
return ret ? MP_SUCCESS : MP_STANDARD_ERROR;
2427
}
2528

2629
/*
@@ -34,11 +37,14 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
3437
size_t buflength, char **newbuffer, size_t maxlength)
3538
{
3639
DWORD left, length, full_length, err;
37-
40+
BOOL ret;
3841
*newbuffer = NULL;
3942

40-
if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
41-
&length, NULL))
43+
Py_BEGIN_ALLOW_THREADS
44+
ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
45+
&length, NULL);
46+
Py_END_ALLOW_THREADS
47+
if (ret)
4248
return length;
4349

4450
err = GetLastError();
@@ -61,7 +67,10 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
6167

6268
memcpy(*newbuffer, buffer, length);
6369

64-
if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) {
70+
Py_BEGIN_ALLOW_THREADS
71+
ret = ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)
72+
Py_END_ALLOW_THREADS
73+
if (ret) {
6574
assert(length == left);
6675
return full_length;
6776
} else {

Modules/_multiprocessing/socket_connection.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,34 +73,38 @@ _conn_recvall(HANDLE h, char *buffer, size_t length)
7373
static Py_ssize_t
7474
conn_send_string(ConnectionObject *conn, char *string, size_t length)
7575
{
76+
Py_ssize_t res;
7677
/* The "header" of the message is a 32 bit unsigned number (in
7778
network order) which specifies the length of the "body". If
7879
the message is shorter than about 16kb then it is quicker to
7980
combine the "header" and the "body" of the message and send
8081
them at once. */
8182
if (length < (16*1024)) {
8283
char *message;
83-
int res;
8484

8585
message = PyMem_Malloc(length+4);
8686
if (message == NULL)
8787
return MP_MEMORY_ERROR;
8888

8989
*(UINT32*)message = htonl((UINT32)length);
9090
memcpy(message+4, string, length);
91+
Py_BEGIN_ALLOW_THREADS
9192
res = _conn_sendall(conn->handle, message, length+4);
93+
Py_END_ALLOW_THREADS
9294
PyMem_Free(message);
93-
return res;
9495
} else {
9596
UINT32 lenbuff;
9697

9798
if (length > MAX_MESSAGE_LENGTH)
9899
return MP_BAD_MESSAGE_LENGTH;
99100

100101
lenbuff = htonl((UINT32)length);
101-
return _conn_sendall(conn->handle, (char*)&lenbuff, 4) ||
102+
Py_BEGIN_ALLOW_THREADS
103+
res = _conn_sendall(conn->handle, (char*)&lenbuff, 4) ||
102104
_conn_sendall(conn->handle, string, length);
105+
Py_END_ALLOW_THREADS
103106
}
107+
return res;
104108
}
105109

106110
/*
@@ -118,7 +122,9 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
118122

119123
*newbuffer = NULL;
120124

125+
Py_BEGIN_ALLOW_THREADS
121126
res = _conn_recvall(conn->handle, (char*)&ulength, 4);
127+
Py_END_ALLOW_THREADS
122128
if (res < 0)
123129
return res;
124130

@@ -127,13 +133,17 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
127133
return MP_BAD_MESSAGE_LENGTH;
128134

129135
if (ulength <= buflength) {
136+
Py_BEGIN_ALLOW_THREADS
130137
res = _conn_recvall(conn->handle, buffer, (size_t)ulength);
138+
Py_END_ALLOW_THREADS
131139
return res < 0 ? res : ulength;
132140
} else {
133141
*newbuffer = PyMem_Malloc((size_t)ulength);
134142
if (*newbuffer == NULL)
135143
return MP_MEMORY_ERROR;
144+
Py_BEGIN_ALLOW_THREADS
136145
res = _conn_recvall(conn->handle, *newbuffer, (size_t)ulength);
146+
Py_END_ALLOW_THREADS
137147
return res < 0 ? (Py_ssize_t)res : (Py_ssize_t)ulength;
138148
}
139149
}

0 commit comments

Comments
 (0)