mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/socket/socket.c (unix_recv_io): prevent FD leak when 2 fd is
sent on LP64 platform. (rsock_discard_cmsg_resource): new function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@22633 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5f305864e5
commit
52a6728bd2
2 changed files with 51 additions and 17 deletions
|
|
@ -1,3 +1,9 @@
|
|||
Wed Feb 25 23:37:56 2009 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* ext/socket/socket.c (unix_recv_io): prevent FD leak when 2 fd is
|
||||
sent on LP64 platform.
|
||||
(rsock_discard_cmsg_resource): new function.
|
||||
|
||||
Wed Feb 25 22:54:13 2009 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* win32/Makefile.sub (config.status): use un.rb as cp instead of
|
||||
|
|
|
|||
|
|
@ -1950,15 +1950,15 @@ unix_recvfrom(argc, argv, sock)
|
|||
}
|
||||
|
||||
#if defined(HAVE_ST_MSG_CONTROL) && defined(SCM_RIGHTS)
|
||||
#define FD_PASSING_BY_MSG_CONTROL 1
|
||||
# define FD_PASSING_BY_MSG_CONTROL 1
|
||||
#else
|
||||
#define FD_PASSING_BY_MSG_CONTROL 0
|
||||
# define FD_PASSING_BY_MSG_CONTROL 0
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ST_MSG_ACCRIGHTS)
|
||||
#define FD_PASSING_BY_MSG_ACCRIGHTS 1
|
||||
# define FD_PASSING_BY_MSG_ACCRIGHTS 1
|
||||
#else
|
||||
#define FD_PASSING_BY_MSG_ACCRIGHTS 0
|
||||
# define FD_PASSING_BY_MSG_ACCRIGHTS 0
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
|
|
@ -2027,6 +2027,28 @@ unix_send_io(sock, val)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_RECVMSG) && FD_PASSING_BY_MSG_CONTROL
|
||||
void
|
||||
rsock_discard_cmsg_resource(struct msghdr *mh)
|
||||
{
|
||||
struct cmsghdr *cmh;
|
||||
|
||||
if (mh->msg_controllen == 0)
|
||||
return;
|
||||
|
||||
for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
|
||||
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) {
|
||||
close(*fdp);
|
||||
fdp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
|
||||
static void
|
||||
thread_read_select(fd)
|
||||
|
|
@ -2097,6 +2119,21 @@ unix_recv_io(argc, argv, sock)
|
|||
rb_sys_fail("recvmsg(2)");
|
||||
|
||||
#if FD_PASSING_BY_MSG_CONTROL
|
||||
if (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)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 (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)",
|
||||
|
|
@ -2108,19 +2145,10 @@ unix_recv_io(argc, argv, sock)
|
|||
(int)msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
|
||||
}
|
||||
if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
|
||||
rb_raise(rb_eSocket,
|
||||
"file descriptor was not passed (cmsg_len=%d, %d expected)",
|
||||
cmsg.hdr.cmsg_len, 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);
|
||||
rsock_discard_cmsg_resource(&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)));
|
||||
}
|
||||
#else
|
||||
if (msg.msg_accrightslen != sizeof(fd)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue