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

ruby-changes:10880

From: akr <ko1@a...>
Date: Thu, 19 Feb 2009 23:01:29 +0900 (JST)
Subject: [ruby-changes:10880] Ruby:r22454 (trunk): * ext/socket/ancdata.c (make_io_for_unix_rights): cmsg_len may be

akr	2009-02-19 23:01:17 +0900 (Thu, 19 Feb 2009)

  New Revision: 22454

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

  Log:
    * ext/socket/ancdata.c (make_io_for_unix_rights): cmsg_len may be
      bigger than msg_controllen.
      freeze unix_rights array.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22453)
+++ ChangeLog	(revision 22454)
@@ -1,3 +1,9 @@
+Thu Feb 19 22:59:09 2009  Tanaka Akira  <akr@f...>
+
+	* ext/socket/ancdata.c (make_io_for_unix_rights): cmsg_len may be
+	  bigger than msg_controllen.
+	  freeze unix_rights array.
+
 Thu Feb 19 22:17:38 2009  Tanaka Akira  <akr@f...>
 
 	* ext/socket/ancdata.c (bsock_recvmsg_internal): fix exception.
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 22453)
+++ ext/socket/ancdata.c	(revision 22454)
@@ -1146,15 +1146,19 @@
 
 #if defined(HAVE_ST_MSG_CONTROL)
 static void
-make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh)
+make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end)
 {
     if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
-        int *fdp = (int *)CMSG_DATA(cmh);
-        int *end = (int *)((char *)cmh + cmh->cmsg_len);
-        while (fdp < end) {
+        int *fdp, *end;
+	VALUE ary = rb_ary_new();
+	rb_ivar_set(ctl, rb_intern("unix_rights"), ary);
+        fdp = (int *)CMSG_DATA(cmh);
+        end = (int *)((char *)cmh + cmh->cmsg_len);
+        while ((char *)fdp + sizeof(int) <= (char *)end &&
+	       (char *)fdp + sizeof(int) <= msg_end) {
             int fd = *fdp;
             struct stat stbuf;
-            VALUE io, ary;
+            VALUE io;
             if (fstat(fd, &stbuf) == -1)
                 rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");
             if (S_ISSOCK(stbuf.st_mode))
@@ -1162,13 +1166,10 @@
             else
                 io = rb_io_fdopen(fd, O_RDWR, NULL);
             ary = rb_attr_get(ctl, rb_intern("unix_rights"));
-            if (NIL_P(ary)) {
-                ary = rb_ary_new();
-                rb_ivar_set(ctl, rb_intern("unix_rights"), ary);
-            }
             rb_ary_push(ary, io);
             fdp++;
         }
+	OBJ_FREEZE(ary);
     }
 }
 #endif
@@ -1343,15 +1344,18 @@
 #if defined(HAVE_ST_MSG_CONTROL)
     family = rb_sock_getfamily(fptr->fd);
     if (mh.msg_controllen) {
+	char *msg_end = (char *)mh.msg_control + mh.msg_controllen;
         for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
             VALUE ctl;
+	    char *ctl_end;
             size_t clen;
             if (cmh->cmsg_len == 0) {
                 rb_raise(rb_eTypeError, "invalid control message (cmsg_len == 0)");
             }
-            clen = (char*)cmh + cmh->cmsg_len - (char*)CMSG_DATA(cmh);
+            ctl_end = (char*)cmh + cmh->cmsg_len;
+	    clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh);
             ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_tainted_str_new((char*)CMSG_DATA(cmh), clen));
-            make_io_for_unix_rights(ctl, cmh);
+            make_io_for_unix_rights(ctl, cmh, msg_end);
             rb_ary_push(ret, ctl);
         }
     }

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

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