From f0f6c8d231b415e5d69575c0c757e10abefdca2b Mon Sep 17 00:00:00 2001 From: PHO Date: Tue, 18 Dec 2012 08:33:50 +0900 Subject: [PATCH] gsocket: Work around broken CMSG_FIRSTHDR() As RFC 2292 points out, some platforms (e.g. Darwin 9.8.0) provide CMSG_FIRSTHDR(msg) which just returns msg.msg_control without first checking if msg.msg_controllen is non-zero. We need a workaround for such platforms not to let g_socket_receive_message() segfault. https://bugzilla.gnome.org/show_bug.cgi?id=690388 --- gio/gsocket.c | 57 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/gio/gsocket.c b/gio/gsocket.c index ebb831c..cb09dfc 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -4154,33 +4154,36 @@ g_socket_receive_message (GSocket *socket, GPtrArray *my_messages = NULL; struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) - { - GSocketControlMessage *message; - - message = g_socket_control_message_deserialize (cmsg->cmsg_level, - cmsg->cmsg_type, - cmsg->cmsg_len - ((char *)CMSG_DATA (cmsg) - (char *)cmsg), - CMSG_DATA (cmsg)); - if (message == NULL) - /* We've already spewed about the problem in the - deserialization code, so just continue */ - continue; - - if (messages == NULL) - { - /* we have to do it this way if the user ignores the - * messages so that we will close any received fds. - */ - g_object_unref (message); - } - else - { - if (my_messages == NULL) - my_messages = g_ptr_array_new (); - g_ptr_array_add (my_messages, message); - } - } + if (msg.msg_controllen >= sizeof (struct cmsghdr)) + { + for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) + { + GSocketControlMessage *message; + + message = g_socket_control_message_deserialize (cmsg->cmsg_level, + cmsg->cmsg_type, + cmsg->cmsg_len - ((char *)CMSG_DATA (cmsg) - (char *)cmsg), + CMSG_DATA (cmsg)); + if (message == NULL) + /* We've already spewed about the problem in the + deserialization code, so just continue */ + continue; + + if (messages == NULL) + { + /* we have to do it this way if the user ignores the + * messages so that we will close any received fds. + */ + g_object_unref (message); + } + else + { + if (my_messages == NULL) + my_messages = g_ptr_array_new (); + g_ptr_array_add (my_messages, message); + } + } + } if (num_messages) *num_messages = my_messages != NULL ? my_messages->len : 0; -- 2.7.4