match_hostname() performs a forward DNS lookup of a hostname token written in
hosts allow / hosts deny and compares the result against the connecting
IP. When that lookup FAILED it returned "no match" -- indistinguishable from
a genuine non-match -- so allow_access() fell through and ADMITTED the
connection. A daemon configured hosts deny = <hostname> therefore silently
accepted the very host it was configured to block.
No attacker DNS control is required. Two ordinary situations produce it:
- a transient resolver failure, and
- a
daemon chroot whose tree lacks resolver configuration. Note this is
the GLOBAL daemon chroot, entered before module selection, not a
per-module use chroot: module access checking runs before the per-module
chroot, so a resolver-less module chroot does not trigger this.
rsyncd.conf(5) does warn that a daemon chroot may need OS and library
files present; an administrator who does not supply resolver
configuration silently loses the deny rule.
forward lookup is enabled by default, so a default daemon that uses hostname
tokens in hosts deny is affected.
Fixed by treating an unresolvable token on a DENY list as a match (deny).
Allow-list tokens keep failing as a non-match, so a resolver failure cannot
grant access through an allow rule either.
The regression drives the fail-open path with a permanently unresolvable
.invalid token; it establishes the behaviour, not a transiently unreachable
real hostname.
This is the sibling of CVE-2026-43617, which fixed only the reverse-lookup
path in the same function; the forward-lookup path was left failing open.
Affected: 3.1.0 through 3.4.4 with forward lookup enabled, which is the DEFAULT (forward lookup of hostname tokens entered in 3.1.0)
Fixed in: 3.5.0
Reporter: Leonid Bugaev (security audit); sibling of CVE-2026-43617
Test: daemon-deny-dns-failopen
match_hostname() performs a forward DNS lookup of a hostname token written in
hosts allow/hosts denyand compares the result against the connectingIP. When that lookup FAILED it returned "no match" -- indistinguishable from
a genuine non-match -- so allow_access() fell through and ADMITTED the
connection. A daemon configured
hosts deny = <hostname>therefore silentlyaccepted the very host it was configured to block.
No attacker DNS control is required. Two ordinary situations produce it:
daemon chrootwhose tree lacks resolver configuration. Note this isthe GLOBAL
daemon chroot, entered before module selection, not aper-module
use chroot: module access checking runs before the per-modulechroot, so a resolver-less module chroot does not trigger this.
rsyncd.conf(5) does warn that a
daemon chrootmay need OS and libraryfiles present; an administrator who does not supply resolver
configuration silently loses the deny rule.
forward lookupis enabled by default, so a default daemon that uses hostnametokens in
hosts denyis affected.Fixed by treating an unresolvable token on a DENY list as a match (deny).
Allow-list tokens keep failing as a non-match, so a resolver failure cannot
grant access through an allow rule either.
The regression drives the fail-open path with a permanently unresolvable
.invalidtoken; it establishes the behaviour, not a transiently unreachablereal hostname.
This is the sibling of CVE-2026-43617, which fixed only the reverse-lookup
path in the same function; the forward-lookup path was left failing open.
Affected: 3.1.0 through 3.4.4 with
forward lookupenabled, which is the DEFAULT (forward lookup of hostname tokens entered in 3.1.0)Fixed in: 3.5.0
Reporter: Leonid Bugaev (security audit); sibling of CVE-2026-43617
Test: daemon-deny-dns-failopen