[#4595] New block syntax — Daniel Amelang <daniel.amelang@...>

I'm really sorry if this isn't the place to talk about this. I've

25 messages 2005/03/21
[#4606] Re: New block syntax — "David A. Black" <dblack@...> 2005/03/21

Hi --

[#4629] Re: New block syntax — "Sean E. Russell" <ser@...> 2005/03/30

On Monday 21 March 2005 16:17, David A. Black wrote:

[#4648] about REXML::Encoding — speakillof <speakillof@...>

Hi.

15 messages 2005/03/31
[#4659] Re: about REXML::Encoding — "Sean E. Russell" <ser@...> 2005/04/04

On Thursday 31 March 2005 09:44, speakillof wrote:

Re: Patch for denial of service vulnerability in WEBrick

From: GOTOU Yuuzou <gotoyuzo@...>
Date: 2005-03-05 20:19:02 UTC
List: ruby-core #4519
Hi,

In message <422935C1.5040905@blackhat.com>,
 `Dominique Brezinski <dom@blackhat.com>' wrote:
> If
> connections are terminated during the SSL handsake, an exception is
> raised that is not properly handled in webrick/server.rb. The result
> is that there is a leak in the token queue used to limit the number of
> threads created to handle connections.

Thanks.

> Here is a patch for 1.8.2 that fixes this and a related leak:

I want to simplify operations about @tokens as soon as
possible. How do you think about the following patch?
-- 
gotoyuzo

--- lib/webrick/server.rb	18 Jan 2005 06:03:43 -0000	1.5.2.4
+++ lib/webrick/server.rb	5 Mar 2005 20:01:17 -0000
@@ -88,17 +88,15 @@     def start(&block)
             if svrs = IO.select(@listeners, nil, nil, 2.0)
               svrs[0].each{|svr|
                 @tokens.pop          # blocks while no token is there.
-                sock = svr.accept
-                sock.sync = true
-                Utils::set_close_on_exec(sock)
-                th = start_thread(sock, &block)
-                th[:WEBrickThread] = true
-                thgroup.add(th)
+                if sock = accept_client(svr)
+                  th = start_thread(sock, &block)
+                  th[:WEBrickThread] = true
+                  thgroup.add(th)
+                else
+                  @tokens.push(nil)
+                end
               }
             end
-          rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex
-            # TCP connection was established but RST segment was sent
-            # from peer before calling TCPServer#accept.
           rescue Errno::EBADF, IOError => ex
             # if the listening socket was closed in GenericServer#shutdown,
             # IO::select raise it.
@@ -140,6 +138,22 @@     def run(sock)
 
     private
 
+    def accept_client(svr)
+      sock = nil
+      begin
+        sock = svr.accept
+        sock.sync = true
+        Utils::set_close_on_exec(sock)
+      rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex
+        # TCP connection was established but RST segment was sent
+        # from peer before calling TCPServer#accept.
+      rescue Exception => ex
+        msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
+        @logger.error msg
+      end
+      return sock
+    end
+
     def start_thread(sock, &block)
       Thread.start{
         begin
@@ -161,6 +175,7 @@     def start_thread(sock, &block)
         rescue Exception => ex
           @logger.error ex
         ensure
+          @tokens.push(nil)
           Thread.current[:WEBrickSocket] = nil
           if addr
             @logger.debug "close: #{addr[3]}:#{addr[1]}"
@@ -169,7 +184,6 @@     def start_thread(sock, &block)
           end
           sock.close
         end
-        @tokens.push(nil)
       }
     end
 

In This Thread