From 4be69d35eb276266b846a8a01481894f35d244dd Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Thu, 16 Dec 2021 15:58:54 +0300 Subject: [PATCH] Pull request: aghnet: do not turn bad etc/hosts entries into rules Updates #3946. Squashed commit of the following: commit 5d632dc4c49325308570adbfbc0fe333528989b5 Author: Ainar Garipov Date: Thu Dec 16 15:49:51 2021 +0300 aghnet: imp code commit 4da620ee625718f5cd7549277c483631f22b977b Author: Ainar Garipov Date: Thu Dec 16 15:33:39 2021 +0300 aghnet: do not turn bad etc/hosts entries into rules --- internal/aghnet/hostscontainer.go | 41 ++++++++++++++++++------------ internal/aghnet/testdata/etc_hosts | 6 +++++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/internal/aghnet/hostscontainer.go b/internal/aghnet/hostscontainer.go index ca8631c2..e4c1678b 100644 --- a/internal/aghnet/hostscontainer.go +++ b/internal/aghnet/hostscontainer.go @@ -100,16 +100,16 @@ const hostsContainerPref = "hosts container" type HostsContainer struct { // requestMatcher matches the requests and translates the rules. It's // embedded to implement MatchRequest and Translate for *HostsContainer. + // + // TODO(a.garipov, e.burkov): Consider fully merging into HostsContainer. requestMatcher - // listID is the identifier for the list of generated rules. - listID int - // done is the channel to sign closing the container. done chan struct{} // updates is the channel for receiving updated hosts. updates chan *netutil.IPMap + // last is the set of hosts that was cached within last detected change. last *netutil.IPMap @@ -118,8 +118,12 @@ type HostsContainer struct { // w tracks the changes in specified files and directories. w aghos.FSWatcher + // patterns stores specified paths in the fs.Glob-compatible form. patterns []string + + // listID is the identifier for the list of generated rules. + listID int } // ErrNoHostsPaths is returned when there are no valid paths to watch passed to @@ -288,7 +292,7 @@ func (hp *hostsParser) parseFile( s := bufio.NewScanner(r) for s.Scan() { ip, hosts := hp.parseLine(s.Text()) - if ip == nil { + if ip == nil || len(hosts) == 0 { continue } @@ -310,21 +314,26 @@ func (hp *hostsParser) parseLine(line string) (ip net.IP, hosts []string) { } for _, f := range fields[1:] { - switch hashIdx := strings.IndexByte(f, '#'); hashIdx { - case -1: - hosts = append(hosts, f) - - continue - case 0: - // Go on. - default: + hashIdx := strings.IndexByte(f, '#') + if hashIdx == 0 { + // The rest of the fields are a part of the comment so return. + break + } else if hashIdx > 0 { // Only a part of the field is a comment. - hosts = append(hosts, f[:hashIdx]) + f = f[:hashIdx] } - // The rest of the fields are a part of the comment so skip - // immediately. - break + // Make sure that invalid hosts aren't turned into rules. + // + // See https://github.com/AdguardTeam/AdGuardHome/issues/3946. + err := netutil.ValidateDomainName(f) + if err != nil { + log.Error("%s: host %q is invalid, ignoring", hostsContainerPref, f) + + continue + } + + hosts = append(hosts, f) } return ip, hosts diff --git a/internal/aghnet/testdata/etc_hosts b/internal/aghnet/testdata/etc_hosts index d3cabac2..15e07566 100644 --- a/internal/aghnet/testdata/etc_hosts +++ b/internal/aghnet/testdata/etc_hosts @@ -8,7 +8,13 @@ # See https://github.com/AdguardTeam/AdGuardHome/issues/3846. 1.0.0.2 a.whole lot.of aliases for.testing +# See https://github.com/AdguardTeam/AdGuardHome/issues/3946. +1.0.0.3 * +1.0.0.4 *.com + # Same for IPv6. ::1 simplehost :: hello hello.world ::2 a.whole lot.of aliases for.testing +::3 * +::4 *.com