Kaydet (Commit) 1299e36a authored tarafından Jesse Noller's avatar Jesse Noller

Submit fix for issue3393: Memory corruption in multiprocessing module

üst 8dbf3649
...@@ -129,9 +129,7 @@ connection_sendbytes(ConnectionObject *self, PyObject *args) ...@@ -129,9 +129,7 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
} }
} }
Py_BEGIN_ALLOW_THREADS
res = conn_send_string(self, buffer + offset, size); res = conn_send_string(self, buffer + offset, size);
Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return mp_SetError(PyExc_IOError, res); return mp_SetError(PyExc_IOError, res);
...@@ -156,10 +154,8 @@ connection_recvbytes(ConnectionObject *self, PyObject *args) ...@@ -156,10 +154,8 @@ connection_recvbytes(ConnectionObject *self, PyObject *args)
return NULL; return NULL;
} }
Py_BEGIN_ALLOW_THREADS
res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE, res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE,
&freeme, maxlength); &freeme, maxlength);
Py_END_ALLOW_THREADS
if (res < 0) { if (res < 0) {
if (res == MP_BAD_MESSAGE_LENGTH) { if (res == MP_BAD_MESSAGE_LENGTH) {
...@@ -208,10 +204,8 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args) ...@@ -208,10 +204,8 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
return NULL; return NULL;
} }
Py_BEGIN_ALLOW_THREADS
res = conn_recv_string(self, buffer+offset, length-offset, res = conn_recv_string(self, buffer+offset, length-offset,
&freeme, PY_SSIZE_T_MAX); &freeme, PY_SSIZE_T_MAX);
Py_END_ALLOW_THREADS
if (res < 0) { if (res < 0) {
if (res == MP_BAD_MESSAGE_LENGTH) { if (res == MP_BAD_MESSAGE_LENGTH) {
...@@ -266,9 +260,7 @@ connection_send_obj(ConnectionObject *self, PyObject *obj) ...@@ -266,9 +260,7 @@ connection_send_obj(ConnectionObject *self, PyObject *obj)
if (PyString_AsStringAndSize(pickled_string, &buffer, &length) < 0) if (PyString_AsStringAndSize(pickled_string, &buffer, &length) < 0)
goto failure; goto failure;
Py_BEGIN_ALLOW_THREADS
res = conn_send_string(self, buffer, (int)length); res = conn_send_string(self, buffer, (int)length);
Py_END_ALLOW_THREADS
if (res < 0) { if (res < 0) {
mp_SetError(PyExc_IOError, res); mp_SetError(PyExc_IOError, res);
...@@ -292,10 +284,8 @@ connection_recv_obj(ConnectionObject *self) ...@@ -292,10 +284,8 @@ connection_recv_obj(ConnectionObject *self)
CHECK_READABLE(self); CHECK_READABLE(self);
Py_BEGIN_ALLOW_THREADS
res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE, res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE,
&freeme, PY_SSIZE_T_MAX); &freeme, PY_SSIZE_T_MAX);
Py_END_ALLOW_THREADS
if (res < 0) { if (res < 0) {
if (res == MP_BAD_MESSAGE_LENGTH) { if (res == MP_BAD_MESSAGE_LENGTH) {
......
...@@ -18,9 +18,12 @@ static Py_ssize_t ...@@ -18,9 +18,12 @@ static Py_ssize_t
conn_send_string(ConnectionObject *conn, char *string, size_t length) conn_send_string(ConnectionObject *conn, char *string, size_t length)
{ {
DWORD amount_written; DWORD amount_written;
BOOL ret;
return WriteFile(conn->handle, string, length, &amount_written, NULL) Py_BEGIN_ALLOW_THREADS
? MP_SUCCESS : MP_STANDARD_ERROR; ret = WriteFile(conn->handle, string, length, &amount_written, NULL);
Py_END_ALLOW_THREADS
return ret ? MP_SUCCESS : MP_STANDARD_ERROR;
} }
/* /*
...@@ -34,11 +37,14 @@ conn_recv_string(ConnectionObject *conn, char *buffer, ...@@ -34,11 +37,14 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
size_t buflength, char **newbuffer, size_t maxlength) size_t buflength, char **newbuffer, size_t maxlength)
{ {
DWORD left, length, full_length, err; DWORD left, length, full_length, err;
BOOL ret;
*newbuffer = NULL; *newbuffer = NULL;
if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength), Py_BEGIN_ALLOW_THREADS
&length, NULL)) ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength),
&length, NULL);
Py_END_ALLOW_THREADS
if (ret)
return length; return length;
err = GetLastError(); err = GetLastError();
...@@ -61,7 +67,10 @@ conn_recv_string(ConnectionObject *conn, char *buffer, ...@@ -61,7 +67,10 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
memcpy(*newbuffer, buffer, length); memcpy(*newbuffer, buffer, length);
if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) { Py_BEGIN_ALLOW_THREADS
ret = ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)
Py_END_ALLOW_THREADS
if (ret) {
assert(length == left); assert(length == left);
return full_length; return full_length;
} else { } else {
......
...@@ -73,6 +73,7 @@ _conn_recvall(HANDLE h, char *buffer, size_t length) ...@@ -73,6 +73,7 @@ _conn_recvall(HANDLE h, char *buffer, size_t length)
static Py_ssize_t static Py_ssize_t
conn_send_string(ConnectionObject *conn, char *string, size_t length) conn_send_string(ConnectionObject *conn, char *string, size_t length)
{ {
Py_ssize_t res;
/* The "header" of the message is a 32 bit unsigned number (in /* The "header" of the message is a 32 bit unsigned number (in
network order) which specifies the length of the "body". If network order) which specifies the length of the "body". If
the message is shorter than about 16kb then it is quicker to the message is shorter than about 16kb then it is quicker to
...@@ -80,7 +81,6 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length) ...@@ -80,7 +81,6 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length)
them at once. */ them at once. */
if (length < (16*1024)) { if (length < (16*1024)) {
char *message; char *message;
int res;
message = PyMem_Malloc(length+4); message = PyMem_Malloc(length+4);
if (message == NULL) if (message == NULL)
...@@ -88,9 +88,10 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length) ...@@ -88,9 +88,10 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length)
*(UINT32*)message = htonl((UINT32)length); *(UINT32*)message = htonl((UINT32)length);
memcpy(message+4, string, length); memcpy(message+4, string, length);
Py_BEGIN_ALLOW_THREADS
res = _conn_sendall(conn->handle, message, length+4); res = _conn_sendall(conn->handle, message, length+4);
Py_END_ALLOW_THREADS
PyMem_Free(message); PyMem_Free(message);
return res;
} else { } else {
UINT32 lenbuff; UINT32 lenbuff;
...@@ -98,9 +99,12 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length) ...@@ -98,9 +99,12 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length)
return MP_BAD_MESSAGE_LENGTH; return MP_BAD_MESSAGE_LENGTH;
lenbuff = htonl((UINT32)length); lenbuff = htonl((UINT32)length);
return _conn_sendall(conn->handle, (char*)&lenbuff, 4) || Py_BEGIN_ALLOW_THREADS
res = _conn_sendall(conn->handle, (char*)&lenbuff, 4) ||
_conn_sendall(conn->handle, string, length); _conn_sendall(conn->handle, string, length);
Py_END_ALLOW_THREADS
} }
return res;
} }
/* /*
...@@ -118,7 +122,9 @@ conn_recv_string(ConnectionObject *conn, char *buffer, ...@@ -118,7 +122,9 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
*newbuffer = NULL; *newbuffer = NULL;
Py_BEGIN_ALLOW_THREADS
res = _conn_recvall(conn->handle, (char*)&ulength, 4); res = _conn_recvall(conn->handle, (char*)&ulength, 4);
Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return res; return res;
...@@ -127,13 +133,17 @@ conn_recv_string(ConnectionObject *conn, char *buffer, ...@@ -127,13 +133,17 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
return MP_BAD_MESSAGE_LENGTH; return MP_BAD_MESSAGE_LENGTH;
if (ulength <= buflength) { if (ulength <= buflength) {
Py_BEGIN_ALLOW_THREADS
res = _conn_recvall(conn->handle, buffer, (size_t)ulength); res = _conn_recvall(conn->handle, buffer, (size_t)ulength);
Py_END_ALLOW_THREADS
return res < 0 ? res : ulength; return res < 0 ? res : ulength;
} else { } else {
*newbuffer = PyMem_Malloc((size_t)ulength); *newbuffer = PyMem_Malloc((size_t)ulength);
if (*newbuffer == NULL) if (*newbuffer == NULL)
return MP_MEMORY_ERROR; return MP_MEMORY_ERROR;
Py_BEGIN_ALLOW_THREADS
res = _conn_recvall(conn->handle, *newbuffer, (size_t)ulength); res = _conn_recvall(conn->handle, *newbuffer, (size_t)ulength);
Py_END_ALLOW_THREADS
return res < 0 ? (Py_ssize_t)res : (Py_ssize_t)ulength; return res < 0 ? (Py_ssize_t)res : (Py_ssize_t)ulength;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment