[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