Re: TCPwrappers race condition

der Mouse (mouse@RODENTS.MONTREAL.QC.CA)
Sun, 05 Oct 1997 08:51:32 -0400

>> Although the time window can be made *smaller* by using results from
>> accept() instead of getpeername(), the time window can be eliminated
>> only by changing the kernel so that it does not destroy the protocol
>> control block when the connection is reset by the peer.

> If accept() does return without an error, why would you not have the
> address? Thus where is the time window?

As the note says, if the kernel destroys the PCB first....

That is, the sequence of events is:

- remote host initiates connection
- local host responds, three-way handshake completes
- local host creates a PCB, queues it to be picked up by a future
accept() call
- remote end tears down the connection
- local host destroys the PCB
- userland finally gets around to calling accept()

But by the time accept() happens, the PCB has been torn down, so
there's no remote address available.

One could argue that this is a bug; I certainly hold this view. There
is room to argue about where the bug is; for example, in this
situation, should the accept() fail? (One can't just destroy the queue
entry, because when the PCB was queued, userland was promised (via a
select() wakeup or equivalent) that accept() would not block.) Or
should the kernel maintain a PCB and mark it as CLOSED so that the
accept() returns an already-shut-down connection? Or what?

Similar remarks apply to getpeername() calls after the accept(). The
only difference is that more time passes between the connection setup
and the time at which the address is needed, so there's more
opportunity for the remote end to tear down the connection.

der Mouse

mouse@rodents.montreal.qc.ca
7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B