asyncore DoS vulnerability

billie gnewsg at gmail.com
Thu Feb 1 14:18:33 EST 2007


Hi all. I've just terminated a server application using asyncore /
asynchat frameworks.
I wrote a test script that performs a lot of connections to the server
app and I discovered that asyncore (or better, select()) can manage
only a limited number of file descriptors (aka simultaneous
connections).
When this number is reached select() raises an error but asyncore
doesn't handle this exception (a crash occurs).
If you want to try this I pasted two scripts below: a server and a
client.
On my Windows XP system server.py the crash occurs when 512
simultaneous connections are reached.
Here's the traceback:

Traceback (most recent call last):
  File "C:\Documents and Settings\root\Desktop\test.py", line 31, in ?
    asyncore.loop(timeout=1)
  File "C:\Python24\lib\asyncore.py", line 192, in loop
    poll_fun(timeout, map)
  File "C:\Python24\lib\asyncore.py", line 122, in poll
    r, w, e = select.select(r, w, e, timeout)
ValueError: too many file descriptors in select()


Why does this exception isn't handled inside asyncore.py?



----------------------------------------------------
# server.py
import asyncore, socket

class server(asyncore.dispatcher):
    """The base class for the backend."""

    def __init__(self):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(('', 8080))
        self.listen(5)

    def handle_accept(self):
        sock_obj, addr = self.accept()
        handler(sock_obj)

class handler(asyncore.dispatcher):

    def __init__(self, sock_obj):
        asyncore.dispatcher.__init__(self, sock=sock_obj)

    def handle_write(self):
        pass

    def handle_read(self):
        pass

server()
asyncore.loop(timeout=1)

-----------------------------------------------------

# client.py
import socket, threading, os

def client():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect(("127.0.0.1", 8080))
    except:
        print x
        os._exit(0)
    while 1:
        s.recv(1024)

x = 0
while 1:
    x +=1
    threading.Thread(target=client).start()
    print x




More information about the Python-list mailing list