[Python-checkins] r65376 - in python/trunk/Modules/_multiprocessing: connection.h pipe_connection.c socket_connection.c

jesse.noller python-checkins at python.org
Fri Aug 1 21:46:50 CEST 2008


Author: jesse.noller
Date: Fri Aug  1 21:46:50 2008
New Revision: 65376

Log:
Submit fix for issue3393: Memory corruption in multiprocessing module

Modified:
   python/trunk/Modules/_multiprocessing/connection.h
   python/trunk/Modules/_multiprocessing/pipe_connection.c
   python/trunk/Modules/_multiprocessing/socket_connection.c

Modified: python/trunk/Modules/_multiprocessing/connection.h
==============================================================================
--- python/trunk/Modules/_multiprocessing/connection.h	(original)
+++ python/trunk/Modules/_multiprocessing/connection.h	Fri Aug  1 21:46:50 2008
@@ -129,9 +129,7 @@
 		}
 	}
 
-	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 @@
 		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 @@
 		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 @@
 	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 @@
 
 	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) {

Modified: python/trunk/Modules/_multiprocessing/pipe_connection.c
==============================================================================
--- python/trunk/Modules/_multiprocessing/pipe_connection.c	(original)
+++ python/trunk/Modules/_multiprocessing/pipe_connection.c	Fri Aug  1 21:46:50 2008
@@ -18,9 +18,12 @@
 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 @@
 		 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 @@
 
 	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 {

Modified: python/trunk/Modules/_multiprocessing/socket_connection.c
==============================================================================
--- python/trunk/Modules/_multiprocessing/socket_connection.c	(original)
+++ python/trunk/Modules/_multiprocessing/socket_connection.c	Fri Aug  1 21:46:50 2008
@@ -73,6 +73,7 @@
 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 @@
 	   them at once. */
 	if (length < (16*1024)) {
 		char *message;
-		int res;
 
 		message = PyMem_Malloc(length+4);
 		if (message == NULL)
@@ -88,9 +88,10 @@
 
 		*(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 @@
 			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 @@
 
 	*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 @@
 		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;
 	}
 }


More information about the Python-checkins mailing list