[glib] GSocket: Use MSG_CMSG_CLOEXEC
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc: 
- Subject: [glib] GSocket: Use MSG_CMSG_CLOEXEC
- Date: Thu,  5 May 2011 18:31:03 +0000 (UTC)
commit 8932a1a7a3bf1bb68c2f2762f3674a149742b1fa
Author: Colin Walters <walters verbum org>
Date:   Thu May 5 13:16:54 2011 -0400
    GSocket: Use MSG_CMSG_CLOEXEC
    
    This ensures received file descriptors don't leak to child processes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=649480
 gio/gsocket.c        |   16 ++++++++++++++++
 gio/gunixfdmessage.c |    4 ++++
 2 files changed, 20 insertions(+), 0 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 4b5f18a..97120a6 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -3290,6 +3290,14 @@ g_socket_receive_message (GSocket                 *socket,
     else
       msg.msg_flags = 0;
 
+    /* We always set the close-on-exec flag so we don't leak file
+     * descriptors into child processes.  Note that gunixfdmessage.c
+     * will later call fcntl (fd, FD_CLOEXEC), but that isn't atomic.
+     */
+#ifdef MSG_CMSG_CLOEXEC
+    msg.msg_flags |= MSG_CMSG_CLOEXEC;
+#endif
+
     /* do it */
     while (1)
       {
@@ -3299,6 +3307,14 @@ g_socket_receive_message (GSocket                 *socket,
 	  return -1;
 
 	result = recvmsg (socket->priv->fd, &msg, msg.msg_flags);
+#ifdef MSG_CMSG_CLOEXEC	
+	if (result < 0 && get_socket_errno () == EINVAL)
+	  {
+	    /* We must be running on an old kernel.  Call without the flag. */
+	    msg.msg_flags &= ~(MSG_CMSG_CLOEXEC);
+	    result = recvmsg (socket->priv->fd, &msg, msg.msg_flags);
+	  }
+#endif
 
 	if (result < 0)
 	  {
diff --git a/gio/gunixfdmessage.c b/gio/gunixfdmessage.c
index ab310bc..a9c5fe1 100644
--- a/gio/gunixfdmessage.c
+++ b/gio/gunixfdmessage.c
@@ -101,6 +101,10 @@ g_unix_fd_message_deserialize (int      level,
   fds = data;
   n = size / sizeof (gint);
 
+  /* Note we probably handled this in gsocket.c already if we're on
+   * Linux and have MSG_CMSG_CLOEXEC, but this code remains as a fallback
+   * in case the kernel is too old for MSG_CMSG_CLOEXEC.
+   */
   for (i = 0; i < n; i++)
     {
       do
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]