Bug 638330 (CVE-2010-3492) - CVE-2010-3492 python accept() implementation in async core is broken
Summary: CVE-2010-3492 python accept() implementation in async core is broken
Keywords:
Status: CLOSED CANTFIX
Alias: CVE-2010-3492
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
low
low
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-09-28 19:26 UTC by Josh Bressers
Modified: 2021-02-24 22:21 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-12-15 20:10:15 UTC
Embargoed:


Attachments (Terms of Use)

Description Josh Bressers 2010-09-28 19:26:05 UTC
From the upstream bug: http://bugs.python.org/issue6706

An old bad design choice in asyncore is how it forces the user to override
handle_accept() and then call self.accept() to obtain a socket pair.

    def handle_accept(self):
        conn, addr = self.accept()

The documentation itself shows the code above as an example of how an
asyncore-based server should handle an incoming connection.  What the doc
doesn't say is that the user calling self.accept() is exposed to different
risks:

- self.accept() can return None instead of a socket pair in which case
TypeError is raised (see pyftpdlib bug: 
http://code.google.com/p/pyftpdlib/issues/detail?id=91)

- ECONNABORTED can be raised. This is reproducible on Linux by hammering
the server with nmap (see pyftpdlib bug: 
http://code.google.com/p/pyftpdlib/issues/detail?id=105)

- EAGAIN can be raised too. I never experienced this error condition 
myself in pyftpdlib but by looking at twisted/internet/tcp.py it seems 
reasonable to catch EAGAIN too.

- The resulting address can be None, which means that the connection didn't
take place.  This is reproducible by hammering the server with nmap (see
pyftpdlib 
bug http://code.google.com/p/pyftpdlib/issues/detail?id=104).


The right thing to do when one of such events occur is to "return" as no
connection has really been established between client and server.

Now, altough handling these kind of conditions is quite easy, the API
design remains fundamentally wrong, as it forces the user to call accept().
As asyncore.py is structured right now the only chance the user has to
properly accepting a connection is manually handling all these cases in his
subclass.

Comment 1 Josh Bressers 2010-12-15 19:29:37 UTC
Upstream has a fix for this now:
http://svn.python.org/view?view=rev&revision=86084

It seems that the fix still can return None, which some clients will not handle gracefully. I suspect the solution is going to be to patch clients, not python itself.

Comment 2 Josh Bressers 2010-12-15 20:10:15 UTC
Statement:

This issue affects the version of the python package as shipped with Red Hat Enterprise Linux 4, 5, and 6. Due to the nature of this flaw, it cannot be fixed in the python language, but must be addressed in each module which calls accept().


Note You need to log in before you can comment on or make changes to this bug.