COMMAND
select(2)/accept(2)
SYSTEMS AFFECTED
NetBSD, other systems?
PROBLEM
Following is based on NetBSD Security Advisory. A problem has
been identified which allows remote attackers to wedge many TCP
services running on 4.4BSD-derived systems, including X servers
and all services run from inetd. Other (non-BSD) systems are
believed to be affected as well. Many TCP servers open a TCP
socket in the default blocking mode, use select(2) to wait for
connections, and then accept(2) connections in blocking mode.
Under some circumstances, the accept(2) may hang waiting for
another connection, denying service to clients trying to connect
to other ports. The scenario which causes this is:
* Connection is initiated by client; 3WHS completes,
* Server process is awakened and select(2) succeeds,
* Connection is closed by client (e.g. by sending a RST).
Connection is removed from accept(2) queue on server,
* Server process does an accept(2), which hangs waiting for a
connection.
This scenario is sometimes difficult to reproduce, particularly if
the server is very fast and the network is relatively slow. It is
most effective if the server is slow and/or must do a lot of work
between the select(2) and accept(2). The same bug shows up in
(for example) select()+write() if there's more than one process
writing to the same open file.
SOLUTION
1) Modify all TCP servers to use non-blocking listening sockets.
Unfortunately, this requires changing a large amount of code,
much of it maintained by third parties.
2) Modify the kernel to not remove sockets from the accept(2)
queue when they are closed. A change that implements this has
been added to NetBSD-current, and is available at:
ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/patches/19990120-accept
One workaround also is to run servers under tcpserver:
http://pobox.com/~djb/ucspi-tcp.html
tcpserver handles a single TCP port with a simple accept() loop.