Why you can't mix wildcard IP port binding with other bindings
A while back I wrote, about TCP port binding:
Unfortunately, you can't bind a port to the generic wildcard address if anyone is using the port on a specific IP address, hence the Apache restart problem. (Why this port binding limitation is a sensible is beyond the scope of this margin, but it is, however annoying it periodically is.)
Today I feel like explaining why. The core problem is deciding who gets handed a new connection (or for UDP, a new packet); if you allow multiple binding, all of the possible answers create security issues.
Imagine that a hypothetical system allowed two different programs
to listen for connections on port 3000, one with a wildcard address
INADDR_ANY) and one specifically with the local address
127.0.0.1. There are generally three useful answers for who gets the
connection when someone connects to port 3000 on 127.0.0.1:
- the program that bound the port with the 127.0.0.1 address.
- the program that bound the port with the wildcard address.
- something different for each connection (a random choice, the first
program to call
accept(), strict alternation, etc).
All of these let a malicious program steal incoming connections from a legitimate program and do nasty things with them. The first two are mirrors of each other and each can hose you in the right circumstances, and the third just means that the malicious program steals only some of the connections instead of all of them.
The one limited way out that I can see is to make binding the second port succeed only if the process doing so is privileged, and have it forcefully close the first port. (If you don't force-close the first port, you open daemons up to subtle connection stealing attacks when they're restarted or started after boot.)
But, really, the simplest way out is to prevent the whole situation coming up in the first place, which is exactly what Unix does. (I suspect Windows does likewise, but I don't know for sure.)
(PS: the title of this entry illustrates how I sometimes can't write good titles.)