[前][次][番号順一覧][スレッド一覧]

ruby-changes:11038

From: akr <ko1@a...>
Date: Wed, 25 Feb 2009 23:03:54 +0900 (JST)
Subject: [ruby-changes:11038] Ruby:r22630 (trunk): * ext/socket/unixsocket.c (unix_recv_io): prevent FD leak when 2 fd is

akr	2009-02-25 23:03:42 +0900 (Wed, 25 Feb 2009)

  New Revision: 22630

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22630

  Log:
    * ext/socket/unixsocket.c (unix_recv_io): prevent FD leak when 2 fd is
      sent on LP64 platform.
    * ext/socket/rubysocket.h (rsock_discard_cmsg_resource): declared.
    
    * ext/socket/ancdata.c (rsock_discard_cmsg_resource): renamed from
      discard_cmsg_resource.  export it.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c
    trunk/ext/socket/rubysocket.h
    trunk/ext/socket/unixsocket.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22629)
+++ ChangeLog	(revision 22630)
@@ -1,3 +1,13 @@
+Wed Feb 25 23:01:26 2009  Tanaka Akira  <akr@f...>
+
+	* ext/socket/unixsocket.c (unix_recv_io): prevent FD leak when 2 fd is
+	  sent on LP64 platform.
+
+	* ext/socket/rubysocket.h (rsock_discard_cmsg_resource): declared.
+
+	* ext/socket/ancdata.c (rsock_discard_cmsg_resource): renamed from
+	  discard_cmsg_resource.  export it.
+
 Wed Feb 25 17:31:32 2009  NAKAMURA Usaku  <usa@r...>
 
 	* io.c (sysopen_func, rb_sysopen_internal, rb_sysopen): open file
Index: ext/socket/rubysocket.h
===================================================================
--- ext/socket/rubysocket.h	(revision 22629)
+++ ext/socket/rubysocket.h	(revision 22630)
@@ -259,6 +259,10 @@
 
 VALUE sockopt_new(int family, int level, int optname, VALUE data);
 
+#ifdef HAVE_ST_MSG_CONTROL
+void rsock_discard_cmsg_resource(struct msghdr *mh);
+#endif
+
 void Init_basicsocket(void);
 void Init_ipsocket(void);
 void Init_tcpsocket(void);
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 22629)
+++ ext/socket/ancdata.c	(revision 22630)
@@ -1300,10 +1300,10 @@
     return rb_thread_blocking_region(nogvl_recvmsg_func, &args, RUBY_UBF_IO, 0);
 }
 
-static void
-discard_cmsg_resource(struct msghdr *mh)
+#if defined(HAVE_ST_MSG_CONTROL)
+void
+rsock_discard_cmsg_resource(struct msghdr *mh)
 {
-#if defined(HAVE_ST_MSG_CONTROL)
     struct cmsghdr *cmh;
 
     if (mh->msg_controllen == 0)
@@ -1319,8 +1319,8 @@
             }
         }
     }
+}
 #endif
-}
 
 #if defined(HAVE_ST_MSG_CONTROL)
 static void
@@ -1505,7 +1505,7 @@
                 /* there are big space bug truncated.
                  * file descriptors limit? */
                 if (!gc_done) {
-		    discard_cmsg_resource(&mh);
+		    rsock_discard_cmsg_resource(&mh);
                     goto gc_and_retry;
 		}
             }
@@ -1526,14 +1526,14 @@
 	}
 #endif
 	if (grown) {
-            discard_cmsg_resource(&mh);
+            rsock_discard_cmsg_resource(&mh);
 	    goto retry;
 	}
 	else {
             grow_buffer = 0;
             if (flags != orig_flags) {
                 flags = orig_flags;
-                discard_cmsg_resource(&mh);
+                rsock_discard_cmsg_resource(&mh);
                 goto retry;
             }
         }
Index: ext/socket/unixsocket.c
===================================================================
--- ext/socket/unixsocket.c	(revision 22629)
+++ ext/socket/unixsocket.c	(revision 22630)
@@ -334,6 +334,21 @@
 	rb_sys_fail("recvmsg(2)");
 
 #if FD_PASSING_BY_MSG_CONTROL
+    if (arg.msg.msg_controllen < sizeof(struct cmsghdr)) {
+	rb_raise(rb_eSocket,
+		 "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
+		 (int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
+    }
+    if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
+	rb_raise(rb_eSocket,
+		 "file descriptor was not passed (cmsg_level=%d, %d expected)",
+		 cmsg.hdr.cmsg_level, SOL_SOCKET);
+    }
+    if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
+	rb_raise(rb_eSocket,
+		 "file descriptor was not passed (cmsg_type=%d, %d expected)",
+		 cmsg.hdr.cmsg_type, SCM_RIGHTS);
+    }
     if (arg.msg.msg_controllen < CMSG_LEN(sizeof(int))) {
 	rb_raise(rb_eSocket,
 		 "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
@@ -345,20 +360,11 @@
 		 (int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
     }
     if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
+	rsock_discard_cmsg_resource(&arg.msg);
 	rb_raise(rb_eSocket,
 		 "file descriptor was not passed (cmsg_len=%d, %d expected)",
 		 (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
     }
-    if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
-	rb_raise(rb_eSocket,
-		 "file descriptor was not passed (cmsg_level=%d, %d expected)",
-		 cmsg.hdr.cmsg_level, SOL_SOCKET);
-    }
-    if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {
-	rb_raise(rb_eSocket,
-		 "file descriptor was not passed (cmsg_type=%d, %d expected)",
-		 cmsg.hdr.cmsg_type, SCM_RIGHTS);
-    }
 #else
     if (arg.msg.msg_accrightslen != sizeof(fd)) {
 	rb_raise(rb_eSocket,

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]