[glib] gsocket: Work around broken CMSG_FIRSTHDR()



commit f0f6c8d231b415e5d69575c0c757e10abefdca2b
Author: PHO <pho cielonegro org>
Date:   Tue Dec 18 08:33:50 2012 +0900

    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 files 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;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]