[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#829650: marked as done (jessie-pu: package ruby-eventmachine/1.0.3-6+deb8u1)



Your message dated Sat, 17 Sep 2016 13:08:06 +0100
with message-id <1474114086.2011.126.camel@adam-barratt.org.uk>
and subject line Closing p-u bugs for updates in 8.6
has caused the Debian Bug report #829650,
regarding jessie-pu: package ruby-eventmachine/1.0.3-6+deb8u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
829650: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=829650
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Dear Release Team,

The Security Team suggested fixing the TEMP-0678512-2E167C [1] security
issue through a point release.

The issue is a remotely triggerable crash due to stack overflow.

Please see the debdiff attached.

The fix for Wheezy which is very similar was discussed [2] on the Wheezy
LTS list.

Cheers,
Balint

[1] https://security-tracker.debian.org/tracker/TEMP-0678512-2E167C
[2] https://lists.debian.org/debian-lts/2016/06/msg00141.html
diff -Nru ruby-eventmachine-1.0.3/debian/changelog ruby-eventmachine-1.0.3/debian/changelog
--- ruby-eventmachine-1.0.3/debian/changelog	2014-04-07 00:34:46.000000000 +0200
+++ ruby-eventmachine-1.0.3/debian/changelog	2016-07-04 22:00:03.000000000 +0200
@@ -1,3 +1,12 @@
+ruby-eventmachine (1.0.3-6+deb8u1) stable; urgency=medium
+
+  * Team upload
+  * Fix remotely triggerable crash due to FD handling
+    (Closes: #678512, #696015)
+  * Fix memory leak caused when fixing crash
+
+ -- Balint Reczey <balint@balintreczey.hu>  Mon, 04 Jul 2016 21:48:06 +0200
+
 ruby-eventmachine (1.0.3-6) unstable; urgency=low
 
   * Bump gem2deb build dependency to 0.7.5~
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0001-use-ruby-select-api-with-expandable-fd-sets.patch ruby-eventmachine-1.0.3/debian/patches/0001-use-ruby-select-api-with-expandable-fd-sets.patch
--- ruby-eventmachine-1.0.3/debian/patches/0001-use-ruby-select-api-with-expandable-fd-sets.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0001-use-ruby-select-api-with-expandable-fd-sets.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,217 @@
+From eab3baaba75c8c9e549aea54d3b356ab287a57b0 Mon Sep 17 00:00:00 2001
+From: Patrick Reynolds <patrick.reynolds@github.com>
+Date: Tue, 11 Mar 2014 16:01:25 -0500
+Subject: [PATCH 1/3] use ruby select api with expandable fd sets
+
+Conflicts:
+	ext/em.h
+---
+ ext/em.cpp             | 54 +++++++++++++++++++++++++-------------------------
+ ext/em.h               | 10 +++++-----
+ tests/test_many_fds.rb | 22 ++++++++++++++++++++
+ 3 files changed, 54 insertions(+), 32 deletions(-)
+ create mode 100644 tests/test_many_fds.rb
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index 670da31..6a3a2ef 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -524,12 +524,12 @@ void EventMachine_t::_RunEpollOnce()
+ 	#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+ 	if ((ret = rb_wait_for_single_fd(epfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
+ 	#else
+-	fd_set fdreads;
++	rb_fdset_t fdreads;
+ 
+-	FD_ZERO(&fdreads);
+-	FD_SET(epfd, &fdreads);
++	rb_fd_init(&fdreads);
++	rb_fd_set(epfd, &fdreads);
+ 
+-	if ((ret = rb_thread_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
++	if ((ret = rb_thread_fd_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
+ 	#endif
+ 		if (ret == -1) {
+ 			assert(errno != EINVAL);
+@@ -601,12 +601,12 @@ void EventMachine_t::_RunKqueueOnce()
+ 	#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+ 	if ((ret = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
+ 	#else
+-	fd_set fdreads;
++	rb_fdset_t fdreads;
+ 
+-	FD_ZERO(&fdreads);
+-	FD_SET(kqfd, &fdreads);
++	rb_fd_init(&fdreads);
++	rb_fd_set(kqfd, &fdreads);
+ 
+-	if ((ret = rb_thread_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
++	if ((ret = rb_thread_fd_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
+ 	#endif
+ 		if (ret == -1) {
+ 			assert(errno != EINVAL);
+@@ -792,9 +792,9 @@ SelectData_t::SelectData_t
+ SelectData_t::SelectData_t()
+ {
+ 	maxsocket = 0;
+-	FD_ZERO (&fdreads);
+-	FD_ZERO (&fdwrites);
+-	FD_ZERO (&fderrors);
++	rb_fd_init (&fdreads);
++	rb_fd_init (&fdwrites);
++	rb_fd_init (&fderrors);
+ }
+ 
+ 
+@@ -807,7 +807,7 @@ _SelectDataSelect
+ static VALUE _SelectDataSelect (void *v)
+ {
+ 	SelectData_t *sd = (SelectData_t*)v;
+-	sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
++	sd->nSockets = rb_fd_select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
+ 	return Qnil;
+ }
+ #endif
+@@ -848,9 +848,9 @@ void EventMachine_t::_RunSelectOnce()
+ 
+ 	SelectData_t SelectData;
+ 	/*
+-	fd_set fdreads, fdwrites;
+-	FD_ZERO (&fdreads);
+-	FD_ZERO (&fdwrites);
++	rb_fdset_t fdreads, fdwrites;
++	rb_fd_init (&fdreads);
++	rb_fd_init (&fdwrites);
+ 
+ 	int maxsocket = 0;
+ 	*/
+@@ -860,7 +860,7 @@ void EventMachine_t::_RunSelectOnce()
+ 	// running on localhost with a randomly-chosen port. (*Puke*)
+ 	// Windows has a version of the Unix pipe() library function, but it doesn't
+ 	// give you back descriptors that are selectable.
+-	FD_SET (LoopBreakerReader, &(SelectData.fdreads));
++	rb_fd_set (LoopBreakerReader, &(SelectData.fdreads));
+ 	if (SelectData.maxsocket < LoopBreakerReader)
+ 		SelectData.maxsocket = LoopBreakerReader;
+ 
+@@ -875,15 +875,15 @@ void EventMachine_t::_RunSelectOnce()
+ 		assert (sd != INVALID_SOCKET);
+ 
+ 		if (ed->SelectForRead())
+-			FD_SET (sd, &(SelectData.fdreads));
++			rb_fd_set (sd, &(SelectData.fdreads));
+ 		if (ed->SelectForWrite())
+-			FD_SET (sd, &(SelectData.fdwrites));
++			rb_fd_set (sd, &(SelectData.fdwrites));
+ 
+ 		#ifdef OS_WIN32
+ 		/* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable.
+ 		   Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html
+ 		*/
+-		FD_SET (sd, &(SelectData.fderrors));
++		rb_fd_set (sd, &(SelectData.fderrors));
+ 		#endif
+ 
+ 		if (SelectData.maxsocket < sd)
+@@ -918,15 +918,15 @@ void EventMachine_t::_RunSelectOnce()
+ 					continue;
+ 				assert (sd != INVALID_SOCKET);
+ 
+-				if (FD_ISSET (sd, &(SelectData.fdwrites)))
++				if (rb_fd_isset (sd, &(SelectData.fdwrites)))
+ 					ed->Write();
+-				if (FD_ISSET (sd, &(SelectData.fdreads)))
++				if (rb_fd_isset (sd, &(SelectData.fdreads)))
+ 					ed->Read();
+-				if (FD_ISSET (sd, &(SelectData.fderrors)))
++				if (rb_fd_isset (sd, &(SelectData.fderrors)))
+ 					ed->HandleError();
+ 			}
+ 
+-			if (FD_ISSET (LoopBreakerReader, &(SelectData.fdreads)))
++			if (rb_fd_isset (LoopBreakerReader, &(SelectData.fdreads)))
+ 				_ReadLoopBreaker();
+ 		}
+ 		else if (s < 0) {
+@@ -964,11 +964,11 @@ void EventMachine_t::_CleanBadDescriptors()
+ 		tv.tv_sec = 0;
+ 		tv.tv_usec = 0;
+ 
+-		fd_set fds;
+-		FD_ZERO(&fds);
+-		FD_SET(sd, &fds);
++		rb_fdset_t fds;
++		rb_fd_init(&fds);
++		rb_fd_set(sd, &fds);
+ 
+-		int ret = select(sd + 1, &fds, NULL, NULL, &tv);
++		int ret = rb_fd_select(sd + 1, &fds, NULL, NULL, &tv);
+ 
+ 		if (ret == -1) {
+ 			if (errno == EBADF)
+diff --git a/ext/em.h b/ext/em.h
+index df68ec1..ff7c26c 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -22,7 +22,7 @@ See the file COPYING for complete licensing information.
+ 
+ #ifdef BUILD_FOR_RUBY
+   #include <ruby.h>
+-  #define EmSelect rb_thread_select
++  #define EmSelect rb_thread_fd_select
+ 
+   #ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+     #include <ruby/io.h>
+@@ -57,7 +57,7 @@ See the file COPYING for complete licensing information.
+     #define RSTRING_LENINT(str) RSTRING_LEN(str)
+   #endif
+ #else
+-  #define EmSelect select
++  #define EmSelect rb_fd_select
+ #endif
+ 
+ class EventableDescriptor;
+@@ -233,9 +233,9 @@ struct SelectData_t
+ 	int _Select();
+ 
+ 	int maxsocket;
+-	fd_set fdreads;
+-	fd_set fdwrites;
+-	fd_set fderrors;
++	rb_fdset_t fdreads;
++	rb_fdset_t fdwrites;
++	rb_fdset_t fderrors;
+ 	timeval tv;
+ 	int nSockets;
+ };
+diff --git a/tests/test_many_fds.rb b/tests/test_many_fds.rb
+new file mode 100644
+index 0000000..74dc926
+--- /dev/null
++++ b/tests/test_many_fds.rb
+@@ -0,0 +1,22 @@
++require 'em_test_helper'
++require 'socket'
++
++class TestManyFDs < Test::Unit::TestCase
++  def setup
++    @port = next_port
++  end
++
++  def test_connection_class_cache
++    mod = Module.new
++    a = nil
++    Process.setrlimit(Process::RLIMIT_NOFILE,4096);
++    EM.run {
++      EM.start_server '127.0.0.1', @port, mod
++      1100.times do
++        a = EM.connect '127.0.0.1', @port, mod
++        assert_kind_of EM::Connection, a
++      end
++      EM.stop
++    }
++  end
++end
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0002-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch ruby-eventmachine-1.0.3/debian/patches/0002-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch
--- ruby-eventmachine-1.0.3/debian/patches/0002-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0002-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,44 @@
+From ef5dac813ef3d10423ec7ca8255eea6d873278f1 Mon Sep 17 00:00:00 2001
+From: Patrick Reynolds <patrick.reynolds@github.com>
+Date: Wed, 12 Mar 2014 00:15:41 -0500
+Subject: [PATCH 2/3] add stubs with warnings for 1.8.7 and 1.9.0
+
+---
+ ext/em.h | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/ext/em.h b/ext/em.h
+index ff7c26c..5b9279d 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -60,6 +60,27 @@ See the file COPYING for complete licensing information.
+   #define EmSelect rb_fd_select
+ #endif
+ 
++#ifndef rb_fd_max
++#define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
++typedef fd_set rb_fdset_t;
++#define rb_fd_zero(f) FD_ZERO(f)
++#define rb_fd_set(n, f) do { if (fd_check(n)) FD_SET((n), (f)); } while(0)
++#define rb_fd_clr(n, f) do { if (fd_check(n)) FD_CLR((n), (f)); } while(0)
++#define rb_fd_isset(n, f) (fd_check(n) ? FD_ISSET((n), (f)) : 0)
++#define rb_fd_copy(d, s, n) (*(d) = *(s))
++#define rb_fd_dup(d, s) (*(d) = *(s))
++#define rb_fd_resize(n, f)  ((void)(f))
++#define rb_fd_ptr(f)  (f)
++#define rb_fd_init(f) FD_ZERO(f)
++#define rb_fd_init_copy(d, s) (*(d) = *(s))
++#define rb_fd_term(f) ((void)(f))
++#define rb_fd_max(f)  FD_SETSIZE
++#define rb_fd_select(n, rfds, wfds, efds, timeout)  \
++  select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout))
++#define rb_thread_fd_select(n, rfds, wfds, efds, timeout)  \
++  rb_thread_select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout))
++#endif
++
+ class EventableDescriptor;
+ class InotifyDescriptor;
+ 
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0003-add-comment-about-where-the-macros-came-from.patch ruby-eventmachine-1.0.3/debian/patches/0003-add-comment-about-where-the-macros-came-from.patch
--- ruby-eventmachine-1.0.3/debian/patches/0003-add-comment-about-where-the-macros-came-from.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0003-add-comment-about-where-the-macros-came-from.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,26 @@
+From 81b673a5a0cd7f96ad7c7bbc6052bbed30b0a2a5 Mon Sep 17 00:00:00 2001
+From: Patrick Reynolds <patrick.reynolds@github.com>
+Date: Wed, 21 Jan 2015 22:34:43 -0600
+Subject: [PATCH 3/3] add comment about where the macros came from
+
+---
+ ext/em.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/ext/em.h b/ext/em.h
+index 5b9279d..05d4310 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -62,6 +62,9 @@ See the file COPYING for complete licensing information.
+ 
+ #ifndef rb_fd_max
+ #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
++// These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
++// with this change: any macros that read or write the nth element of an
++// fdset first call fd_check to make sure n is in bounds.
+ typedef fd_set rb_fdset_t;
+ #define rb_fd_zero(f) FD_ZERO(f)
+ #define rb_fd_set(n, f) do { if (fd_check(n)) FD_SET((n), (f)); } while(0)
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0004-must-call-raw-select-from-thread_blocking_region.patch ruby-eventmachine-1.0.3/debian/patches/0004-must-call-raw-select-from-thread_blocking_region.patch
--- ruby-eventmachine-1.0.3/debian/patches/0004-must-call-raw-select-from-thread_blocking_region.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0004-must-call-raw-select-from-thread_blocking_region.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,25 @@
+From 2fac7f4df1be8f04e4ef0d8f6887686dff66833a Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 22:29:00 -0800
+Subject: [PATCH 04/11] must call raw select() from thread_blocking_region
+
+---
+ ext/em.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index 6a3a2ef..a279893 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -807,7 +807,7 @@ _SelectDataSelect
+ static VALUE _SelectDataSelect (void *v)
+ {
+ 	SelectData_t *sd = (SelectData_t*)v;
+-	sd->nSockets = rb_fd_select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
++	sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
+ 	return Qnil;
+ }
+ #endif
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0005-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch ruby-eventmachine-1.0.3/debian/patches/0005-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch
--- ruby-eventmachine-1.0.3/debian/patches/0005-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0005-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,66 @@
+From ee8b84b9c183edadb6d7daad61a1d7ce80a0abc2 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 22:31:25 -0800
+Subject: [PATCH 05/11] epoll/kqueue on older rubies (without
+ rb_wait_for_single_fd) should use rb_thread_select with regular fdset
+
+epoll/kqueue fds are created early during ruby boot, so it is highly
+unlikely that they will ever overflow FD_SETSIZE
+---
+ ext/em.cpp | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index a279893..392bc9d 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -524,12 +524,12 @@ void EventMachine_t::_RunEpollOnce()
+ 	#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+ 	if ((ret = rb_wait_for_single_fd(epfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
+ 	#else
+-	rb_fdset_t fdreads;
++	fd_set fdreads;
+ 
+-	rb_fd_init(&fdreads);
+-	rb_fd_set(epfd, &fdreads);
++	FD_ZERO(&fdreads);
++	FD_SET(epfd, &fdreads);
+ 
+-	if ((ret = rb_thread_fd_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
++	if ((ret = rb_thread_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
+ 	#endif
+ 		if (ret == -1) {
+ 			assert(errno != EINVAL);
+@@ -601,12 +601,12 @@ void EventMachine_t::_RunKqueueOnce()
+ 	#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+ 	if ((ret = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
+ 	#else
+-	rb_fdset_t fdreads;
++	fd_set fdreads;
+ 
+-	rb_fd_init(&fdreads);
+-	rb_fd_set(kqfd, &fdreads);
++	FD_ZERO(&fdreads);
++	FD_SET(kqfd, &fdreads);
+ 
+-	if ((ret = rb_thread_fd_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
++	if ((ret = rb_thread_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
+ 	#endif
+ 		if (ret == -1) {
+ 			assert(errno != EINVAL);
+@@ -848,9 +848,9 @@ void EventMachine_t::_RunSelectOnce()
+ 
+ 	SelectData_t SelectData;
+ 	/*
+-	rb_fdset_t fdreads, fdwrites;
+-	rb_fd_init (&fdreads);
+-	rb_fd_init (&fdwrites);
++	fd_set fdreads, fdwrites;
++	FD_ZERO (&fdreads);
++	FD_ZERO (&fdwrites);
+ 
+ 	int maxsocket = 0;
+ 	*/
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0006-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch ruby-eventmachine-1.0.3/debian/patches/0006-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch
--- ruby-eventmachine-1.0.3/debian/patches/0006-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0006-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,42 @@
+From 18b256281c80513b8f4724261a29de4b3846249b Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 22:32:19 -0800
+Subject: [PATCH 06/11] make sure to clean up rb_fd_init memory during shutdown
+
+---
+ ext/em.cpp | 6 ++++++
+ ext/em.h   | 1 +
+ 2 files changed, 7 insertions(+)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index 392bc9d..e2a0e2b 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -797,6 +797,12 @@ SelectData_t::SelectData_t()
+ 	rb_fd_init (&fderrors);
+ }
+ 
++SelectData_t::~SelectData_t()
++{
++	rb_fd_term (&fdreads);
++	rb_fd_term (&fdwrites);
++	rb_fd_term (&fderrors);
++}
+ 
+ #ifdef BUILD_FOR_RUBY
+ /*****************
+diff --git a/ext/em.h b/ext/em.h
+index 05d4310..870623d 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -253,6 +253,7 @@ struct SelectData_t
+ struct SelectData_t
+ {
+ 	SelectData_t();
++	~SelectData_t();
+ 
+ 	int _Select();
+ 
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0007-keep-BUILD_FOR_RUBY-compat.patch ruby-eventmachine-1.0.3/debian/patches/0007-keep-BUILD_FOR_RUBY-compat.patch
--- ruby-eventmachine-1.0.3/debian/patches/0007-keep-BUILD_FOR_RUBY-compat.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0007-keep-BUILD_FOR_RUBY-compat.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,29 @@
+From 32b1a0e8499526247f2dccc35ec66768165994f6 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 22:40:10 -0800
+Subject: [PATCH 07/11] keep BUILD_FOR_RUBY compat
+
+---
+ ext/em.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/em.h b/ext/em.h
+index 870623d..3799bba 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -57,10 +57,10 @@ See the file COPYING for complete licensing information.
+     #define RSTRING_LENINT(str) RSTRING_LEN(str)
+   #endif
+ #else
+-  #define EmSelect rb_fd_select
++  #define EmSelect select
+ #endif
+ 
+-#ifndef rb_fd_max
++#if defined(BUILD_FOR_RUBY) && !defined(rb_fd_max)
+ #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
+ // These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
+ // with this change: any macros that read or write the nth element of an
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0008-fix-memory-leak-in-_CleanBadDescriptors.patch ruby-eventmachine-1.0.3/debian/patches/0008-fix-memory-leak-in-_CleanBadDescriptors.patch
--- ruby-eventmachine-1.0.3/debian/patches/0008-fix-memory-leak-in-_CleanBadDescriptors.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0008-fix-memory-leak-in-_CleanBadDescriptors.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,24 @@
+From 01e5539bc8580cdef648bc42c0cb23ee54240d27 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 22:40:23 -0800
+Subject: [PATCH 08/11] fix memory leak in _CleanBadDescriptors
+
+---
+ ext/em.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index e2a0e2b..eb4a080 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -975,6 +975,7 @@ void EventMachine_t::_CleanBadDescriptors()
+ 		rb_fd_set(sd, &fds);
+ 
+ 		int ret = rb_fd_select(sd + 1, &fds, NULL, NULL, &tv);
++		rb_fd_term(&fds);
+ 
+ 		if (ret == -1) {
+ 			if (errno == EBADF)
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0009-use-rb_thread_fd_select-whenever-possible.patch ruby-eventmachine-1.0.3/debian/patches/0009-use-rb_thread_fd_select-whenever-possible.patch
--- ruby-eventmachine-1.0.3/debian/patches/0009-use-rb_thread_fd_select-whenever-possible.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0009-use-rb_thread_fd_select-whenever-possible.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,41 @@
+From 5e990ec9429c2a5797567a735452b80a5d6dc6ff Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 23:24:32 -0800
+Subject: [PATCH 09/11] use rb_thread_fd_select whenever possible
+
+Conflicts:
+	ext/em.cpp
+---
+ ext/em.cpp | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index eb4a080..27ea088 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -809,7 +809,8 @@ SelectData_t::~SelectData_t()
+ _SelectDataSelect
+ *****************/
+ 
+-#ifdef HAVE_TBR
++
++#if !defined(HAVE_RB_THREAD_FD_SELECT) && defined(HAVE_TBR)
+ static VALUE _SelectDataSelect (void *v)
+ {
+ 	SelectData_t *sd = (SelectData_t*)v;
+@@ -824,7 +825,11 @@ SelectData_t::_Select
+ 
+ int SelectData_t::_Select()
+ {
+-	#ifdef HAVE_TBR
++	#if defined(HAVE_RB_THREAD_FD_SELECT)
++	// added in ruby 1.9.2
++	return rb_thread_fd_select (maxsocket+1, &fdreads, &fdwrites, &fderrors, &tv);
++	#elif defined(HAVE_TBR)
++	// added in ruby 1.9.1, deprecated in ruby 2.0.0
+ 	rb_thread_blocking_region (_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0);
+ 	return nSockets;
+ 	#endif
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0010-fix-build-on-ruby-1.9.1.patch ruby-eventmachine-1.0.3/debian/patches/0010-fix-build-on-ruby-1.9.1.patch
--- ruby-eventmachine-1.0.3/debian/patches/0010-fix-build-on-ruby-1.9.1.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0010-fix-build-on-ruby-1.9.1.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,69 @@
+From 6c59b07c500b36274788abe47b34103a3a8586a6 Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 23:45:00 -0800
+Subject: [PATCH 10/11] fix build on ruby 1.9.1
+
+Conflicts:
+	ext/extconf.rb
+---
+ ext/em.cpp     | 2 +-
+ ext/em.h       | 9 +++++++--
+ ext/extconf.rb | 2 ++
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index 27ea088..315d7d7 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -814,7 +814,7 @@ _SelectDataSelect
+ static VALUE _SelectDataSelect (void *v)
+ {
+ 	SelectData_t *sd = (SelectData_t*)v;
+-	sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
++	sd->nSockets = select (sd->maxsocket+1, rb_fd_ptr(&(sd->fdreads)), rb_fd_ptr(&(sd->fdwrites)), rb_fd_ptr(&(sd->fderrors)), &(sd->tv));
+ 	return Qnil;
+ }
+ #endif
+diff --git a/ext/em.h b/ext/em.h
+index 3799bba..86909ad 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -22,7 +22,12 @@ See the file COPYING for complete licensing information.
+ 
+ #ifdef BUILD_FOR_RUBY
+   #include <ruby.h>
+-  #define EmSelect rb_thread_fd_select
++  #ifdef HAVE_RB_THREAD_FD_SELECT
++    #define EmSelect rb_thread_fd_select
++  #else
++    // ruby 1.9.1 and below
++    #define EmSelect rb_thread_select
++  #endif
+ 
+   #ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
+     #include <ruby/io.h>
+@@ -60,7 +65,7 @@ See the file COPYING for complete licensing information.
+   #define EmSelect select
+ #endif
+ 
+-#if defined(BUILD_FOR_RUBY) && !defined(rb_fd_max)
++#if defined(BUILD_FOR_RUBY) && !defined(HAVE_RB_FDSET_T)
+ #define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
+ // These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
+ // with this change: any macros that read or write the nth element of an
+diff --git a/ext/extconf.rb b/ext/extconf.rb
+index 448802a..28cd687 100644
+--- a/ext/extconf.rb
++++ b/ext/extconf.rb
+@@ -70,6 +70,8 @@ add_define "HAVE_TBR" if have_func('rb_thread_blocking_region')# and have_macro(
+ add_define "HAVE_INOTIFY" if inotify = have_func('inotify_init', 'sys/inotify.h')
+ add_define "HAVE_OLD_INOTIFY" if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
+ add_define 'HAVE_WRITEV' if have_func('writev', 'sys/uio.h')
++add_define 'HAVE_RB_THREAD_FD_SELECT' if have_func('rb_thread_fd_select')
++add_define 'HAVE_RB_FDSET_T' if have_type('rb_fdset_t', 'ruby/intern.h')
+ 
+ have_func('rb_wait_for_single_fd')
+ have_func('rb_enable_interrupt')
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/0011-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch ruby-eventmachine-1.0.3/debian/patches/0011-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch
--- ruby-eventmachine-1.0.3/debian/patches/0011-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch	1970-01-01 01:00:00.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/0011-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch	2016-07-04 22:00:03.000000000 +0200
@@ -0,0 +1,144 @@
+From 6e75c507e1bb27e44f205a4ee3e1b138bbbff5ab Mon Sep 17 00:00:00 2001
+From: Aman Gupta <aman@tmm1.net>
+Date: Mon, 9 Feb 2015 23:59:11 -0800
+Subject: [PATCH 11/11] allocate one SelectData_t per reactor to avoid heap
+ allocation on every tick
+
+Conflicts:
+	ext/em.cpp
+---
+ ext/em.cpp | 43 ++++++++++++++++++++-----------------------
+ ext/em.h   |  3 ++-
+ 2 files changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/ext/em.cpp b/ext/em.cpp
+index 315d7d7..326dbe8 100644
+--- a/ext/em.cpp
++++ b/ext/em.cpp
+@@ -101,6 +101,7 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
+ 	#endif
+ 
+ 	_InitializeLoopBreaker();
++	SelectData = new SelectData_t();
+ }
+ 
+ 
+@@ -130,6 +131,8 @@ EventMachine_t::~EventMachine_t()
+ 		close (epfd);
+ 	if (kqfd != -1)
+ 		close (kqfd);
++
++	delete SelectData;
+ }
+ 
+ 
+@@ -856,24 +859,18 @@ void EventMachine_t::_RunSelectOnce()
+ 	// epoll will be effective if we provide it as an alternative,
+ 	// however it has the same problem interoperating with Ruby
+ 	// threads that select does.
+-
+-	SelectData_t SelectData;
+-	/*
+-	fd_set fdreads, fdwrites;
+-	FD_ZERO (&fdreads);
+-	FD_ZERO (&fdwrites);
+-
+-	int maxsocket = 0;
+-	*/
++	rb_fd_zero (&SelectData->fdreads);
++	rb_fd_zero (&SelectData->fdwrites);
++	rb_fd_zero (&SelectData->fderrors);
+ 
+ 	// Always read the loop-breaker reader.
+ 	// Changed 23Aug06, provisionally implemented for Windows with a UDP socket
+ 	// running on localhost with a randomly-chosen port. (*Puke*)
+ 	// Windows has a version of the Unix pipe() library function, but it doesn't
+ 	// give you back descriptors that are selectable.
+-	rb_fd_set (LoopBreakerReader, &(SelectData.fdreads));
+-	if (SelectData.maxsocket < LoopBreakerReader)
+-		SelectData.maxsocket = LoopBreakerReader;
++	rb_fd_set (LoopBreakerReader, &(SelectData->fdreads));
++	if (SelectData->maxsocket < LoopBreakerReader)
++		SelectData->maxsocket = LoopBreakerReader;
+ 
+ 	// prepare the sockets for reading and writing
+ 	size_t i;
+@@ -886,27 +883,27 @@ void EventMachine_t::_RunSelectOnce()
+ 		assert (sd != INVALID_SOCKET);
+ 
+ 		if (ed->SelectForRead())
+-			rb_fd_set (sd, &(SelectData.fdreads));
++			rb_fd_set (sd, &(SelectData->fdreads));
+ 		if (ed->SelectForWrite())
+-			rb_fd_set (sd, &(SelectData.fdwrites));
++			rb_fd_set (sd, &(SelectData->fdwrites));
+ 
+ 		#ifdef OS_WIN32
+ 		/* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable.
+ 		   Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html
+ 		*/
+-		rb_fd_set (sd, &(SelectData.fderrors));
++		rb_fd_set (sd, &(SelectData->fderrors));
+ 		#endif
+ 
+-		if (SelectData.maxsocket < sd)
+-			SelectData.maxsocket = sd;
++		if (SelectData->maxsocket < sd)
++			SelectData->maxsocket = sd;
+ 	}
+ 
+ 
+ 	{ // read and write the sockets
+ 		//timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000.
+ 		//timeval tv = Quantum;
+-		SelectData.tv = _TimeTilNextEvent();
+-		int s = SelectData._Select();
++		SelectData->tv = _TimeTilNextEvent();
++		int s = SelectData->_Select();
+ 		//rb_thread_blocking_region(xxx,(void*)&SelectData,RUBY_UBF_IO,0);
+ 		//int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv));
+ 		//int s = SelectData.nSockets;
+@@ -929,15 +926,15 @@ void EventMachine_t::_RunSelectOnce()
+ 					continue;
+ 				assert (sd != INVALID_SOCKET);
+ 
+-				if (rb_fd_isset (sd, &(SelectData.fdwrites)))
++				if (rb_fd_isset (sd, &(SelectData->fdwrites)))
+ 					ed->Write();
+-				if (rb_fd_isset (sd, &(SelectData.fdreads)))
++				if (rb_fd_isset (sd, &(SelectData->fdreads)))
+ 					ed->Read();
+-				if (rb_fd_isset (sd, &(SelectData.fderrors)))
++				if (rb_fd_isset (sd, &(SelectData->fderrors)))
+ 					ed->HandleError();
+ 			}
+ 
+-			if (rb_fd_isset (LoopBreakerReader, &(SelectData.fdreads)))
++			if (rb_fd_isset (LoopBreakerReader, &(SelectData->fdreads)))
+ 				_ReadLoopBreaker();
+ 		}
+ 		else if (s < 0) {
+diff --git a/ext/em.h b/ext/em.h
+index 86909ad..cdcca23 100644
+--- a/ext/em.h
++++ b/ext/em.h
+@@ -91,7 +91,7 @@ typedef fd_set rb_fdset_t;
+ 
+ class EventableDescriptor;
+ class InotifyDescriptor;
+-
++struct SelectData_t;
+ 
+ /********************
+ class EventMachine_t
+@@ -234,6 +234,7 @@ class EventMachine_t
+ 
+ 	private:
+ 		bool bTerminateSignalReceived;
++		SelectData_t *SelectData;
+ 
+ 		bool bEpoll;
+ 		int epfd; // Epoll file-descriptor
+-- 
+2.1.4
+
diff -Nru ruby-eventmachine-1.0.3/debian/patches/series ruby-eventmachine-1.0.3/debian/patches/series
--- ruby-eventmachine-1.0.3/debian/patches/series	2014-01-21 22:32:58.000000000 +0100
+++ ruby-eventmachine-1.0.3/debian/patches/series	2016-07-04 22:00:03.000000000 +0200
@@ -1 +1,12 @@
 skip_tests_using_network.patch
+0001-use-ruby-select-api-with-expandable-fd-sets.patch
+0002-add-stubs-with-warnings-for-1.8.7-and-1.9.0.patch
+0003-add-comment-about-where-the-macros-came-from.patch
+0004-must-call-raw-select-from-thread_blocking_region.patch
+0005-epoll-kqueue-on-older-rubies-without-rb_wait_for_sin.patch
+0006-make-sure-to-clean-up-rb_fd_init-memory-during-shutd.patch
+0007-keep-BUILD_FOR_RUBY-compat.patch
+0008-fix-memory-leak-in-_CleanBadDescriptors.patch
+0009-use-rb_thread_fd_select-whenever-possible.patch
+0010-fix-build-on-ruby-1.9.1.patch
+0011-allocate-one-SelectData_t-per-reactor-to-avoid-heap-.patch

--- End Message ---
--- Begin Message ---
Version: 8.6

The updates referred to in each of these bugs were included in today's
stable point release.

Regards,

Adam

--- End Message ---

Reply to: