torcontrol: Limit what a Tor control port reply can do #36653

pull fametrano wants to merge 3 commits into bitcoin:master from fametrano:torcontrol-trust-bounds changing 8 files +315 −16
  1. fametrano commented at 8:34 PM on October 24, 2026: none

    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.

  2. DrahtBot commented at 8:34 PM on October 24, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36497 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36497.svg"></sub> (test: Add coverage for TorControl SAFECOOKIE authentication by winterrdog)
    • #36374 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36374.svg"></sub> (torcontrol: escape backslashes in -torpassword by 0xShadowX)
    • #36170 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36170.svg"></sub> (net: require a dedicated bind for automatic Tor by l0rinc)
    • #36167 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36167.svg"></sub> ([RFC] Enable -Wunused by fanquake)
    • #36142 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36142.svg"></sub> (net: validate Tor onion service replies and cached keys by l0rinc)
    • #35713 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35713.svg"></sub> (Remove boost as a unit test runner by rustaceanrob)
    • #35292 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35292.svg"></sub> (test: Add coverage for Tor control HASHEDPASSWORD authentication by winterrdog)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. torcontrol: Only read a regular file as authentication cookie
    The path of the cookie file comes from the reply to PROTOCOLINFO, so
    whatever answers on the control port chooses it. A FIFO with no writer
    made fopen() block the torcontrol thread for good, and shutdown waits
    for that thread.
    
    Check that the path is a regular file before reading it, and log a
    warning if it is not or cannot be examined. Also have ReadBinaryFile
    open the file with O_NONBLOCK on POSIX systems, so that a file replaced
    by a FIFO after the check cannot block either.
    6d994c29f1
  4. torcontrol: Only use a SOCKS listener on the Tor control host
    The reply to GETINFO net/listeners/socks is used as the proxy for onion
    addresses. Whoever answers on the control port can name any address,
    and all onion connections then go through it.
    
    Only accept a listener on the host that runs the control port: a
    loopback address if the control port is on loopback, otherwise the
    address the control port was reached at. Log a warning for each other
    listener, including a unix socket. This keeps working a remote Tor
    reached with -torcontrol, which a loopback-only rule would break.
    
    If no listener is accepted, keep the onion proxy that is already set,
    such as the one from -proxy, instead of replacing it with 127.0.0.1:9050.
    Without one, the default 127.0.0.1:9050 is still used. A listener on
    127.0.0.1 is still preferred over other accepted ones.
    e445a64d7e
  5. doc: Say that the Tor control port is trusted
    Bitcoin Core connects to 127.0.0.1:9051 by default whenever it listens,
    even if Tor is not running. Document that whatever answers there is
    trusted, for instance for the onion address the node advertises.
    3e9e292a1d
  6. DrahtBot added the label CI failed on Oct 24, 2026
  7. DrahtBot removed the label CI failed on Oct 24, 2026
  8. sedited commented at 9:32 PM on October 25, 2026: contributor

    This doesn't seem worthwhile to fix. As you say these interactions are already trusted. I don't think the file becoming a named pipe is really relevant to protect against, especially if all that happens is a hang. There's probably a bunch of other things that can be manipulated too.

  9. sedited closed this on Oct 25, 2026


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-10-30 15:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me