ruby-changes:20590
From: akr <ko1@a...>
Date: Sat, 23 Jul 2011 17:18:21 +0900 (JST)
Subject: [ruby-changes:20590] akr:r32638 (trunk, ruby_1_9_3): * io.c (rb_update_max_fd): validate fd.
akr 2011-07-23 17:13:37 +0900 (Sat, 23 Jul 2011) New Revision: 32638 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32638 Log: * io.c (rb_update_max_fd): validate fd. * ext/socket/rubysocket.h (rsock_discard_cmsg_resource): add msg_peek_p argument for the declaration. * ext/socket/ancdata.c (discard_cmsg): add msg_peek_p argument. assume FreeBSD, NetBSD and MacOS X doesn't generate passed fd when MSG_PEEK. (rsock_discard_cmsg_resource): add msg_peek_p argument. (bsock_recvmsg_internal): call rsock_discard_cmsg_resource with msg_peek_p argument. * ext/socket/unixsocket.c (unix_recv_io): call rsock_discard_cmsg_resource with msg_peek_p argument. Modified files: branches/ruby_1_9_3/ChangeLog branches/ruby_1_9_3/ext/socket/ancdata.c branches/ruby_1_9_3/ext/socket/rubysocket.h branches/ruby_1_9_3/ext/socket/unixsocket.c branches/ruby_1_9_3/io.c trunk/ChangeLog trunk/ext/socket/ancdata.c trunk/ext/socket/rubysocket.h trunk/ext/socket/unixsocket.c trunk/io.c Index: ChangeLog =================================================================== --- ChangeLog (revision 32637) +++ ChangeLog (revision 32638) @@ -1,3 +1,20 @@ +Sat Jul 23 17:06:25 2011 Tanaka Akira <akr@f...> + + * io.c (rb_update_max_fd): validate fd. + + * ext/socket/rubysocket.h (rsock_discard_cmsg_resource): add + msg_peek_p argument for the declaration. + + * ext/socket/ancdata.c (discard_cmsg): add msg_peek_p argument. + assume FreeBSD, NetBSD and MacOS X doesn't generate passed fd + when MSG_PEEK. + (rsock_discard_cmsg_resource): add msg_peek_p argument. + (bsock_recvmsg_internal): call rsock_discard_cmsg_resource with + msg_peek_p argument. + + * ext/socket/unixsocket.c (unix_recv_io): call + rsock_discard_cmsg_resource with msg_peek_p argument. + Sat Jul 23 14:38:28 2011 Eric Hodel <drbrain@s...> * test/rake*: Remove dependencies on flexmock and session gems. Index: io.c =================================================================== --- io.c (revision 32637) +++ io.c (revision 32638) @@ -154,6 +154,10 @@ void rb_update_max_fd(int fd) { + struct stat buf; + if (fstat(fd, &buf) != 0) { + rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd); + } if (max_file_descriptor < fd) max_file_descriptor = fd; } Index: ext/socket/rubysocket.h =================================================================== --- ext/socket/rubysocket.h (revision 32637) +++ ext/socket/rubysocket.h (revision 32638) @@ -288,7 +288,7 @@ #endif #ifdef HAVE_ST_MSG_CONTROL -void rsock_discard_cmsg_resource(struct msghdr *mh); +void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p); #endif void rsock_init_basicsocket(void); Index: ext/socket/ancdata.c =================================================================== --- ext/socket/ancdata.c (revision 32637) +++ ext/socket/ancdata.c (revision 32638) @@ -1377,23 +1377,25 @@ #if defined(HAVE_ST_MSG_CONTROL) static void -discard_cmsg(struct cmsghdr *cmh, char *msg_end) +discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p) { +# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) + /* + * nagachika finds recvmsg with MSG_PEEK doesn't return fds on MacOS X Snow Leopard. [ruby-dev:44209] + * naruse finds FreeBSD behaves as so too and comment in kernel of FreeBSD 8.2.0. [ruby-dev:44189] + * kosaki finds same comment in MacOS X Snow Leopard. [ruby-dev:44192] + * Takahiro Kambe finds same comment since NetBSD 5. [ruby-dev:44205] + */ + if (msg_peek_p) + return; +# endif 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 ((char *)fdp + sizeof(int) <= (char *)end && (char *)fdp + sizeof(int) <= msg_end) { - /* - * xxx: nagachika said *fdp can be invalid fd on MacOS X Lion. - * This workaround using fstat is clearly wrong. - * we should investigate why *fdp contains invalid fd. - */ - struct stat buf; - if (fstat(*fdp, &buf) == 0) { - rb_update_max_fd(*fdp); - close(*fdp); - } + rb_update_max_fd(*fdp); + close(*fdp); fdp++; } } @@ -1401,7 +1403,7 @@ #endif void -rsock_discard_cmsg_resource(struct msghdr *mh) +rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p) { #if defined(HAVE_ST_MSG_CONTROL) struct cmsghdr *cmh; @@ -1413,7 +1415,7 @@ msg_end = (char *)mh->msg_control + mh->msg_controllen; for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) { - discard_cmsg(cmh, msg_end); + discard_cmsg(cmh, msg_end, msg_peek_p); } #endif } @@ -1612,7 +1614,7 @@ /* there are big space bug truncated. * file descriptors limit? */ if (!gc_done) { - rsock_discard_cmsg_resource(&mh); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto gc_and_retry; } } @@ -1633,14 +1635,14 @@ } #endif if (grown) { - rsock_discard_cmsg_resource(&mh); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto retry; } else { grow_buffer = 0; if (flags != orig_flags) { + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); flags = orig_flags; - rsock_discard_cmsg_resource(&mh); goto retry; } } @@ -1680,7 +1682,7 @@ if (request_scm_rights) make_io_for_unix_rights(ctl, cmh, msg_end); else - discard_cmsg(cmh, msg_end); + discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0); rb_ary_push(ret, ctl); } } Index: ext/socket/unixsocket.c =================================================================== --- ext/socket/unixsocket.c (revision 32637) +++ ext/socket/unixsocket.c (revision 32638) @@ -367,7 +367,7 @@ (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); + rsock_discard_cmsg_resource(&arg.msg, 0); rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_len=%d, %d expected)", (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); Index: ruby_1_9_3/ChangeLog =================================================================== --- ruby_1_9_3/ChangeLog (revision 32637) +++ ruby_1_9_3/ChangeLog (revision 32638) @@ -1,3 +1,20 @@ +Sat Jul 23 17:06:25 2011 Tanaka Akira <akr@f...> + + * io.c (rb_update_max_fd): validate fd. + + * ext/socket/rubysocket.h (rsock_discard_cmsg_resource): add + msg_peek_p argument for the declaration. + + * ext/socket/ancdata.c (discard_cmsg): add msg_peek_p argument. + assume FreeBSD, NetBSD and MacOS X doesn't generate passed fd + when MSG_PEEK. + (rsock_discard_cmsg_resource): add msg_peek_p argument. + (bsock_recvmsg_internal): call rsock_discard_cmsg_resource with + msg_peek_p argument. + + * ext/socket/unixsocket.c (unix_recv_io): call + rsock_discard_cmsg_resource with msg_peek_p argument. + Sat Jul 23 14:38:28 2011 Eric Hodel <drbrain@s...> * test/rake*: Remove dependencies on flexmock and session gems. Index: ruby_1_9_3/io.c =================================================================== --- ruby_1_9_3/io.c (revision 32637) +++ ruby_1_9_3/io.c (revision 32638) @@ -154,6 +154,10 @@ void rb_update_max_fd(int fd) { + struct stat buf; + if (fstat(fd, &buf) != 0) { + rb_bug("rb_update_max_fd: invalid fd (%d) given.", fd); + } if (max_file_descriptor < fd) max_file_descriptor = fd; } Index: ruby_1_9_3/ext/socket/rubysocket.h =================================================================== --- ruby_1_9_3/ext/socket/rubysocket.h (revision 32637) +++ ruby_1_9_3/ext/socket/rubysocket.h (revision 32638) @@ -288,7 +288,7 @@ #endif #ifdef HAVE_ST_MSG_CONTROL -void rsock_discard_cmsg_resource(struct msghdr *mh); +void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p); #endif void rsock_init_basicsocket(void); Index: ruby_1_9_3/ext/socket/ancdata.c =================================================================== --- ruby_1_9_3/ext/socket/ancdata.c (revision 32637) +++ ruby_1_9_3/ext/socket/ancdata.c (revision 32638) @@ -1377,23 +1377,25 @@ #if defined(HAVE_ST_MSG_CONTROL) static void -discard_cmsg(struct cmsghdr *cmh, char *msg_end) +discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p) { +# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) + /* + * nagachika finds recvmsg with MSG_PEEK doesn't return fds on MacOS X Snow Leopard. [ruby-dev:44209] + * naruse finds FreeBSD behaves as so too and comment in kernel of FreeBSD 8.2.0. [ruby-dev:44189] + * kosaki finds same comment in MacOS X Snow Leopard. [ruby-dev:44192] + * Takahiro Kambe finds same comment since NetBSD 5. [ruby-dev:44205] + */ + if (msg_peek_p) + return; +# endif 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 ((char *)fdp + sizeof(int) <= (char *)end && (char *)fdp + sizeof(int) <= msg_end) { - /* - * xxx: nagachika said *fdp can be invalid fd on MacOS X Lion. - * This workaround using fstat is clearly wrong. - * we should investigate why *fdp contains invalid fd. - */ - struct stat buf; - if (fstat(*fdp, &buf) == 0) { - rb_update_max_fd(*fdp); - close(*fdp); - } + rb_update_max_fd(*fdp); + close(*fdp); fdp++; } } @@ -1401,7 +1403,7 @@ #endif void -rsock_discard_cmsg_resource(struct msghdr *mh) +rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p) { #if defined(HAVE_ST_MSG_CONTROL) struct cmsghdr *cmh; @@ -1413,7 +1415,7 @@ msg_end = (char *)mh->msg_control + mh->msg_controllen; for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) { - discard_cmsg(cmh, msg_end); + discard_cmsg(cmh, msg_end, msg_peek_p); } #endif } @@ -1612,7 +1614,7 @@ /* there are big space bug truncated. * file descriptors limit? */ if (!gc_done) { - rsock_discard_cmsg_resource(&mh); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto gc_and_retry; } } @@ -1633,14 +1635,14 @@ } #endif if (grown) { - rsock_discard_cmsg_resource(&mh); + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); goto retry; } else { grow_buffer = 0; if (flags != orig_flags) { + rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0); flags = orig_flags; - rsock_discard_cmsg_resource(&mh); goto retry; } } @@ -1680,7 +1682,7 @@ if (request_scm_rights) make_io_for_unix_rights(ctl, cmh, msg_end); else - discard_cmsg(cmh, msg_end); + discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0); rb_ary_push(ret, ctl); } } Index: ruby_1_9_3/ext/socket/unixsocket.c =================================================================== --- ruby_1_9_3/ext/socket/unixsocket.c (revision 32637) +++ ruby_1_9_3/ext/socket/unixsocket.c (revision 32638) @@ -367,7 +367,7 @@ (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); + rsock_discard_cmsg_resource(&arg.msg, 0); rb_raise(rb_eSocket, "file descriptor was not passed (cmsg_len=%d, %d expected)", (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int))); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/