summaryrefslogtreecommitdiffstats
path: root/ext/socket/unixsocket.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-25 14:03:42 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-25 14:03:42 +0000
commit02ecc45247ee9ab4dba4e00f558ff1f64de69677 (patch)
tree31e084992be8f5ae0fcc6c598cd7b56dd9c4d9bc /ext/socket/unixsocket.c
parent1160f163099b138cf24239873cd74201886673de (diff)
downloadruby-02ecc45247ee9ab4dba4e00f558ff1f64de69677.tar.gz
ruby-02ecc45247ee9ab4dba4e00f558ff1f64de69677.tar.xz
ruby-02ecc45247ee9ab4dba4e00f558ff1f64de69677.zip
* 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. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@22630 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/unixsocket.c')
-rw-r--r--ext/socket/unixsocket.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c
index 93d2d107a..5f8b86099 100644
--- a/ext/socket/unixsocket.c
+++ b/ext/socket/unixsocket.c
@@ -334,6 +334,21 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
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 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
(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,