A program that answers on the Tor control port can hang the node at shutdown and point its onion connections at another host.
I now accept the cookie file named in the PROTOCOLINFO reply only if it is a regular file. A FIFO made fopen() block the torcontrol thread, and shutdown waits for that thread. On POSIX the file is opened with O_NONBLOCK, so a swap to a FIFO after the check does not block either.
I also use the SOCKS listener from GETINFO net/listeners/socks only if it is on the control port's host. That is a loopback address if the control port is on loopback, and the -torcontrol host otherwise. Other listeners, including unix sockets, are ignored and a warning is logged. The program can no longer name another host.
If no listener qualifies, I keep the onion proxy set by -proxy instead of replacing it with 127.0.0.1:9050. A remote Tor whose SOCKS listener is on the -torcontrol host keeps working. A remote Tor that listens for SOCKS on another address now needs -onion, or a -proxy that points to it.
Two cases stay open. A program on a loopback control port can still name a loopback listener of its own, and a regular file on a filesystem whose read never returns can still block shutdown.
Tests:
- a unit test for the listener rule in
torcontrol_tests; - a FIFO case in
util_tests; - functional tests in
feature_torcontrol.py, with the mock Tor server, for the cookie file and the listeners.
doc/tor.md says that the control port is trusted, and a release note describes the change.