]> granicus.if.org Git - python/commitdiff
Submit fix for issue3393: Memory corruption in multiprocessing module
authorJesse Noller <jnoller@gmail.com>
Fri, 1 Aug 2008 19:46:50 +0000 (19:46 +0000)
committerJesse Noller <jnoller@gmail.com>
Fri, 1 Aug 2008 19:46:50 +0000 (19:46 +0000)
Modules/_multiprocessing/connection.h
Modules/_multiprocessing/pipe_connection.c
Modules/_multiprocessing/socket_connection.c

index 8e2f7c20c638de19f675bf511850e42c5e1db037..4b475c6bf72787456ffee87efe9a40099e05af8b 100644 (file)
@@ -129,9 +129,7 @@ connection_sendbytes(ConnectionObject *self, PyObject *args)
                }
        }
 
-       Py_BEGIN_ALLOW_THREADS
        res = conn_send_string(self, buffer + offset, size);
-       Py_END_ALLOW_THREADS
 
        if (res < 0)
                return mp_SetError(PyExc_IOError, res);
@@ -156,10 +154,8 @@ connection_recvbytes(ConnectionObject *self, PyObject *args)
                return NULL;
        }
        
-       Py_BEGIN_ALLOW_THREADS
        res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE, 
                               &freeme, maxlength);
-       Py_END_ALLOW_THREADS
        
        if (res < 0) {
                if (res == MP_BAD_MESSAGE_LENGTH) {
@@ -208,10 +204,8 @@ connection_recvbytes_into(ConnectionObject *self, PyObject *args)
                return NULL;
        }
 
-       Py_BEGIN_ALLOW_THREADS
        res = conn_recv_string(self, buffer+offset, length-offset, 
                               &freeme, PY_SSIZE_T_MAX);
-       Py_END_ALLOW_THREADS
 
        if (res < 0) {
                if (res == MP_BAD_MESSAGE_LENGTH) {
@@ -266,9 +260,7 @@ connection_send_obj(ConnectionObject *self, PyObject *obj)
        if (PyString_AsStringAndSize(pickled_string, &buffer, &length) < 0)
                goto failure;
 
-       Py_BEGIN_ALLOW_THREADS
        res = conn_send_string(self, buffer, (int)length);
-       Py_END_ALLOW_THREADS
 
        if (res < 0) {
                mp_SetError(PyExc_IOError, res);
@@ -292,10 +284,8 @@ connection_recv_obj(ConnectionObject *self)
 
        CHECK_READABLE(self);
 
-       Py_BEGIN_ALLOW_THREADS
        res = conn_recv_string(self, self->buffer, CONNECTION_BUFFER_SIZE, 
                               &freeme, PY_SSIZE_T_MAX);
-       Py_END_ALLOW_THREADS
 
        if (res < 0) {
                if (res == MP_BAD_MESSAGE_LENGTH) {
index 1592cca2f24d7d53c7c0db0cdefb4d15b678a898..d655c50aa49619e4a3a4e4ab6f8508e474499aae 100644 (file)
@@ -18,9 +18,12 @@ static Py_ssize_t
 conn_send_string(ConnectionObject *conn, char *string, size_t length)
 {
        DWORD amount_written;
+       BOOL ret;
 
-       return WriteFile(conn->handle, string, length, &amount_written, NULL)
-               ? MP_SUCCESS : MP_STANDARD_ERROR;
+       Py_BEGIN_ALLOW_THREADS
+       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,
                 size_t buflength, char **newbuffer, size_t maxlength)
 {
        DWORD left, length, full_length, err;
-
+       BOOL ret;
        *newbuffer = NULL;
 
-       if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength), 
-                    &length, NULL))
+       Py_BEGIN_ALLOW_THREADS
+       ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength), 
+                     &length, NULL);
+       Py_END_ALLOW_THREADS
+       if (ret)
                return length;
 
        err = GetLastError();
@@ -61,7 +67,10 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
 
        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);
                return full_length;
        } else {
index a6ff9dd26bca386aa22e3b7e9ba1b6537c14c838..e5d2d155d9fed6585ff984dcc618d2b0da67d935 100644 (file)
@@ -73,6 +73,7 @@ _conn_recvall(HANDLE h, char *buffer, size_t length)
 static Py_ssize_t
 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
           network order) which specifies the length of the "body".  If
           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)
           them at once. */
        if (length < (16*1024)) {
                char *message;
-               int res;
 
                message = PyMem_Malloc(length+4);
                if (message == NULL)
@@ -88,9 +88,10 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length)
 
                *(UINT32*)message = htonl((UINT32)length);     
                memcpy(message+4, string, length);
+               Py_BEGIN_ALLOW_THREADS
                res = _conn_sendall(conn->handle, message, length+4);
+               Py_END_ALLOW_THREADS
                PyMem_Free(message);
-               return res;
        } else {
                UINT32 lenbuff;
 
@@ -98,9 +99,12 @@ conn_send_string(ConnectionObject *conn, char *string, size_t length)
                        return MP_BAD_MESSAGE_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);
+               Py_END_ALLOW_THREADS
        }
+       return res;
 }
 
 /*
@@ -118,7 +122,9 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
 
        *newbuffer = NULL;
 
+       Py_BEGIN_ALLOW_THREADS
        res = _conn_recvall(conn->handle, (char*)&ulength, 4);
+       Py_END_ALLOW_THREADS
        if (res < 0)
                return res;
 
@@ -127,13 +133,17 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
                return MP_BAD_MESSAGE_LENGTH;
 
        if (ulength <= buflength) {
+               Py_BEGIN_ALLOW_THREADS
                res = _conn_recvall(conn->handle, buffer, (size_t)ulength);
+               Py_END_ALLOW_THREADS
                return res < 0 ? res : ulength;
        } else {
                *newbuffer = PyMem_Malloc((size_t)ulength);
                if (*newbuffer == NULL)
                        return MP_MEMORY_ERROR;
+               Py_BEGIN_ALLOW_THREADS
                res = _conn_recvall(conn->handle, *newbuffer, (size_t)ulength);
+               Py_END_ALLOW_THREADS
                return res < 0 ? (Py_ssize_t)res : (Py_ssize_t)ulength;
        }
 }