[CalendarServer-changes] [8038] CalendarServer/trunk/twext/python/sendmsg.c

source_changes at macosforge.org source_changes at macosforge.org
Wed Aug 31 23:19:34 PDT 2011


Revision: 8038
          http://trac.macosforge.org/projects/calendarserver/changeset/8038
Author:   glyph at apple.com
Date:     2011-08-31 23:19:34 -0700 (Wed, 31 Aug 2011)
Log Message:
-----------
Compile warnings-clean; typecast everything properly and check for overflows when converting to potentially smaller types.

Modified Paths:
--------------
    CalendarServer/trunk/twext/python/sendmsg.c

Modified: CalendarServer/trunk/twext/python/sendmsg.c
===================================================================
--- CalendarServer/trunk/twext/python/sendmsg.c	2011-09-01 04:35:24 UTC (rev 8037)
+++ CalendarServer/trunk/twext/python/sendmsg.c	2011-09-01 06:19:34 UTC (rev 8038)
@@ -14,11 +14,30 @@
  * limitations under the License.
  */
 
+#define PY_SSIZE_T_CLEAN 1
 #include <Python.h>
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+/* This may cause some warnings, but if you want to get rid of them, upgrade
+ * your Python version.  */
+typedef int Py_ssize_t;
+#endif
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <signal.h>
 
+/*
+ * As per
+ * <http://pubs.opengroup.org/onlinepubs/007904875/basedefs/sys/socket.h.html
+ * #tag_13_61_05>:
+ *
+ *     "To forestall portability problems, it is recommended that applications
+ *     not use values larger than (2**31)-1 for the socklen_t type."
+ */
+
+#define SOCKLEN_MAX 0x7FFFFFFF
+
 PyObject *sendmsg_socket_error;
 
 static PyObject *sendmsg_sendmsg(PyObject *self, PyObject *args, PyObject *keywds);
@@ -91,7 +110,7 @@
 
     int fd;
     int flags = 0;
-    int sendmsg_result;
+    Py_ssize_t sendmsg_result;
     struct msghdr message_header;
     struct iovec iov[1];
     PyObject *ancillary = NULL;
@@ -134,12 +153,13 @@
             return NULL;
         }
 
-        int all_data_len = 0;
+        size_t all_data_len = 0;
 
         /* First we need to know how big the buffer needs to be in order to
            have enough space for all of the messages. */
         while ( (item = PyIter_Next(iterator)) ) {
-            int data_len, type, level;
+            int type, level;
+            Py_ssize_t data_len;
             char *data;
             if (!PyArg_ParseTuple(item, "iit#:sendmsg ancillary data (level, type, data)",
                                   &level,
@@ -161,6 +181,12 @@
         /* Allocate the buffer for all of the ancillary elements, if we have
          * any.  */
         if (all_data_len) {
+            if (all_data_len > SOCKLEN_MAX) {
+                PyErr_Format(PyExc_OverflowError,
+                             "Too much msg_control to fit in a socklen_t: %zu",
+                             all_data_len);
+                return NULL;
+            }
             message_header.msg_control = malloc(all_data_len);
             if (!message_header.msg_control) {
                 PyErr_NoMemory();
@@ -169,7 +195,7 @@
         } else {
             message_header.msg_control = NULL;
         }
-        message_header.msg_controllen = all_data_len;
+        message_header.msg_controllen = (socklen_t) all_data_len;
 
         iterator = PyObject_GetIter(ancillary); /* again */
         item = NULL;
@@ -183,6 +209,7 @@
         struct cmsghdr *control_message = CMSG_FIRSTHDR(&message_header);
         while ( (item = PyIter_Next(iterator)) ) {
             int data_len, type, level;
+            size_t data_size;
             unsigned char *data, *cmsg_data;
 
             /* We explicitly allocated enough space for all ancillary data
@@ -203,8 +230,21 @@
 
             control_message->cmsg_level = level;
             control_message->cmsg_type = type;
-            control_message->cmsg_len = CMSG_LEN(data_len);
+            data_size = CMSG_LEN(data_len);
 
+            if (data_size > SOCKLEN_MAX) {
+                Py_DECREF(item);
+                Py_DECREF(iterator);
+                free(message_header.msg_control);
+
+                PyErr_Format(PyExc_OverflowError,
+                             "CMSG_LEN(%d) > SOCKLEN_MAX", data_len);
+
+                return NULL;
+            }
+
+            control_message->cmsg_len = (socklen_t) data_size;
+
             cmsg_data = CMSG_DATA(control_message);
             memcpy(cmsg_data, data, data_len);
 
@@ -212,9 +252,9 @@
 
             control_message = CMSG_NXTHDR(&message_header, control_message);
         }
-        
+
         Py_DECREF(iterator);
-        
+
         if (PyErr_Occurred()) {
             free(message_header.msg_control);
             return NULL;
@@ -231,15 +271,17 @@
         return NULL;
     }
 
-    return Py_BuildValue("i", sendmsg_result);
+    return Py_BuildValue("n", sendmsg_result);
 }
 
 static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds) {
     int fd = -1;
     int flags = 0;
-    size_t maxsize = 8192;
-    size_t cmsg_size = 4*1024;
-    int recvmsg_result;
+    int maxsize = 8192;
+    int cmsg_size = 4*1024;
+    size_t cmsg_space;
+    Py_ssize_t recvmsg_result;
+
     struct msghdr message_header;
     struct cmsghdr *control_message;
     struct iovec iov[1];
@@ -254,8 +296,16 @@
         return NULL;
     }
 
-    cmsg_size = CMSG_SPACE(cmsg_size);
+    cmsg_space = CMSG_SPACE(cmsg_size);
 
+    /* overflow check */
+    if (cmsg_space > SOCKLEN_MAX) {
+        PyErr_Format(PyExc_OverflowError,
+                     "CMSG_SPACE(cmsg_size) greater than SOCKLEN_MAX: %d",
+                     cmsg_size);
+        return NULL;
+    }
+
     message_header.msg_name = NULL;
     message_header.msg_namelen = 0;
 
@@ -270,7 +320,7 @@
     message_header.msg_iov = iov;
     message_header.msg_iovlen = 1;
 
-    cmsgbuf = malloc(cmsg_size);
+    cmsgbuf = malloc(cmsg_space);
 
     if (!cmsgbuf) {
         free(iov[0].iov_base);
@@ -278,9 +328,10 @@
         return NULL;
     }
 
-    memset(cmsgbuf, 0, cmsg_size);
+    memset(cmsgbuf, 0, cmsg_space);
     message_header.msg_control = cmsgbuf;
-    message_header.msg_controllen = cmsg_size;
+    /* see above for overflow check */
+    message_header.msg_controllen = (socklen_t) cmsg_space;
 
     recvmsg_result = recvmsg(fd, &message_header, flags);
     if (recvmsg_result < 0) {
@@ -313,7 +364,7 @@
             control_message->cmsg_level,
             control_message->cmsg_type,
             CMSG_DATA(control_message),
-            control_message->cmsg_len - sizeof(struct cmsghdr));
+            (Py_ssize_t) (control_message->cmsg_len - sizeof(struct cmsghdr)));
 
         if (!entry) {
             Py_DECREF(ancillary);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110831/7eb8b678/attachment-0001.html>


More information about the calendarserver-changes mailing list