* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c93ed570a2
commit
2bcd502a71
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
Sat Jul 23 17:06:25 2011 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@segment7.net>
|
Sat Jul 23 14:38:28 2011 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
* test/rake*: Remove dependencies on flexmock and session gems.
|
* test/rake*: Remove dependencies on flexmock and session gems.
|
||||||
|
@ -1377,23 +1377,25 @@ rb_recvmsg(int fd, struct msghdr *msg, int flags)
|
|||||||
|
|
||||||
#if defined(HAVE_ST_MSG_CONTROL)
|
#if defined(HAVE_ST_MSG_CONTROL)
|
||||||
static void
|
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) {
|
if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
|
||||||
int *fdp = (int *)CMSG_DATA(cmh);
|
int *fdp = (int *)CMSG_DATA(cmh);
|
||||||
int *end = (int *)((char *)cmh + cmh->cmsg_len);
|
int *end = (int *)((char *)cmh + cmh->cmsg_len);
|
||||||
while ((char *)fdp + sizeof(int) <= (char *)end &&
|
while ((char *)fdp + sizeof(int) <= (char *)end &&
|
||||||
(char *)fdp + sizeof(int) <= msg_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);
|
rb_update_max_fd(*fdp);
|
||||||
close(*fdp);
|
close(*fdp);
|
||||||
}
|
|
||||||
fdp++;
|
fdp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1401,7 +1403,7 @@ discard_cmsg(struct cmsghdr *cmh, char *msg_end)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
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)
|
#if defined(HAVE_ST_MSG_CONTROL)
|
||||||
struct cmsghdr *cmh;
|
struct cmsghdr *cmh;
|
||||||
@ -1413,7 +1415,7 @@ rsock_discard_cmsg_resource(struct msghdr *mh)
|
|||||||
msg_end = (char *)mh->msg_control + mh->msg_controllen;
|
msg_end = (char *)mh->msg_control + mh->msg_controllen;
|
||||||
|
|
||||||
for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
|
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
|
#endif
|
||||||
}
|
}
|
||||||
@ -1612,7 +1614,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
|
|||||||
/* there are big space bug truncated.
|
/* there are big space bug truncated.
|
||||||
* file descriptors limit? */
|
* file descriptors limit? */
|
||||||
if (!gc_done) {
|
if (!gc_done) {
|
||||||
rsock_discard_cmsg_resource(&mh);
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||||||
goto gc_and_retry;
|
goto gc_and_retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1633,14 +1635,14 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (grown) {
|
if (grown) {
|
||||||
rsock_discard_cmsg_resource(&mh);
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
grow_buffer = 0;
|
grow_buffer = 0;
|
||||||
if (flags != orig_flags) {
|
if (flags != orig_flags) {
|
||||||
|
rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
|
||||||
flags = orig_flags;
|
flags = orig_flags;
|
||||||
rsock_discard_cmsg_resource(&mh);
|
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1680,7 +1682,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
|
|||||||
if (request_scm_rights)
|
if (request_scm_rights)
|
||||||
make_io_for_unix_rights(ctl, cmh, msg_end);
|
make_io_for_unix_rights(ctl, cmh, msg_end);
|
||||||
else
|
else
|
||||||
discard_cmsg(cmh, msg_end);
|
discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
|
||||||
rb_ary_push(ret, ctl);
|
rb_ary_push(ret, ctl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ST_MSG_CONTROL
|
#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
|
#endif
|
||||||
|
|
||||||
void rsock_init_basicsocket(void);
|
void rsock_init_basicsocket(void);
|
||||||
|
@ -367,7 +367,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
|
|||||||
(int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
|
(int)arg.msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
|
||||||
}
|
}
|
||||||
if (cmsg.hdr.cmsg_len != CMSG_LEN(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,
|
rb_raise(rb_eSocket,
|
||||||
"file descriptor was not passed (cmsg_len=%d, %d expected)",
|
"file descriptor was not passed (cmsg_len=%d, %d expected)",
|
||||||
(int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
|
(int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
|
||||||
|
4
io.c
4
io.c
@ -154,6 +154,10 @@ static int max_file_descriptor = NOFILE;
|
|||||||
void
|
void
|
||||||
rb_update_max_fd(int fd)
|
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;
|
if (max_file_descriptor < fd) max_file_descriptor = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user