From: Mateusz Poliwczak Date: Sat, 6 Aug 2022 05:42:25 +0000 (+0000) Subject: net: discard unrooted 254 byte names, not rooted ones X-Git-Tag: go1.20rc1~1695 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9e4638ad20181ba4c3b1985da48c56be121901fb;p=gostls13.git net: discard unrooted 254 byte names, not rooted ones Fixes #54285 Change-Id: I20d4d6b9d0532d8a344582b99d446352ae94edcf GitHub-Last-Rev: ad1337450caeaab80755d2951dd01422a906eacc GitHub-Pull-Request: golang/go#54293 Reviewed-on: https://go-review.googlesource.com/c/go/+/421674 TryBot-Result: Gopher Robot Reviewed-by: Damien Neil Run-TryBot: Damien Neil Reviewed-by: Than McIntosh --- diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go index 088c81adee..cc0bf244ea 100644 --- a/src/net/dnsclient_unix.go +++ b/src/net/dnsclient_unix.go @@ -482,7 +482,7 @@ func (conf *dnsConfig) nameList(name string) []string { // Check name length (see isDomainName). l := len(name) rooted := l > 0 && name[l-1] == '.' - if l > 254 || l == 254 && rooted { + if l > 254 || l == 254 && !rooted { return nil } diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 415c53e1e7..17798e434b 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -2216,3 +2216,131 @@ func TestDNSPacketSize(t *testing.T) { t.Errorf("lookup failed: %v", err) } } + +func TestLongDNSNames(t *testing.T) { + const longDNSsuffix = ".go.dev." + const longDNSsuffixNoEndingDot = ".go.dev" + + var longDNSPrefix = strings.Repeat("verylongdomainlabel.", 20) + + var longDNSNamesTests = []struct { + req string + fail bool + }{ + {req: longDNSPrefix[:255-len(longDNSsuffix)] + longDNSsuffix, fail: true}, + {req: longDNSPrefix[:254-len(longDNSsuffix)] + longDNSsuffix}, + {req: longDNSPrefix[:253-len(longDNSsuffix)] + longDNSsuffix}, + + {req: longDNSPrefix[:253-len(longDNSsuffixNoEndingDot)] + longDNSsuffixNoEndingDot}, + {req: longDNSPrefix[:254-len(longDNSsuffixNoEndingDot)] + longDNSsuffixNoEndingDot, fail: true}, + } + + fake := fakeDNSServer{ + rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + }, + Questions: q.Questions, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: q.Questions[0].Type, + Class: dnsmessage.ClassINET, + }, + }, + }, + } + + switch q.Questions[0].Type { + case dnsmessage.TypeA: + r.Answers[0].Body = &dnsmessage.AResource{A: TestAddr} + case dnsmessage.TypeAAAA: + r.Answers[0].Body = &dnsmessage.AAAAResource{AAAA: TestAddr6} + case dnsmessage.TypeTXT: + r.Answers[0].Body = &dnsmessage.TXTResource{TXT: []string{"."}} + case dnsmessage.TypeMX: + r.Answers[0].Body = &dnsmessage.MXResource{ + MX: dnsmessage.MustNewName("go.dev."), + } + case dnsmessage.TypeNS: + r.Answers[0].Body = &dnsmessage.NSResource{ + NS: dnsmessage.MustNewName("go.dev."), + } + case dnsmessage.TypeSRV: + r.Answers[0].Body = &dnsmessage.SRVResource{ + Target: dnsmessage.MustNewName("go.dev."), + } + default: + panic("unknown dnsmessage type") + } + + return r, nil + }, + } + + r := &Resolver{PreferGo: true, Dial: fake.DialContext} + + methodTests := []string{"CNAME", "Host", "IP", "IPAddr", "MX", "NS", "NetIP", "SRV", "TXT"} + query := func(t string, req string) error { + switch t { + case "CNAME": + _, err := r.LookupCNAME(context.Background(), req) + return err + case "Host": + _, err := r.LookupHost(context.Background(), req) + return err + case "IP": + _, err := r.LookupIP(context.Background(), "ip", req) + return err + case "IPAddr": + _, err := r.LookupIPAddr(context.Background(), req) + return err + case "MX": + _, err := r.LookupMX(context.Background(), req) + return err + case "NS": + _, err := r.LookupNS(context.Background(), req) + return err + case "NetIP": + _, err := r.LookupNetIP(context.Background(), "ip", req) + return err + case "SRV": + const service = "service" + const proto = "proto" + req = req[len(service)+len(proto)+4:] + _, _, err := r.LookupSRV(context.Background(), service, proto, req) + return err + case "TXT": + _, err := r.LookupTXT(context.Background(), req) + return err + } + panic("unknown query method") + } + + for i, v := range longDNSNamesTests { + for _, testName := range methodTests { + err := query(testName, v.req) + if v.fail { + if err == nil { + t.Errorf("%v: Lookup%v: unexpected success", i, testName) + break + } + + expectedErr := DNSError{Err: errNoSuchHost.Error(), Name: v.req, IsNotFound: true} + var dnsErr *DNSError + errors.As(err, &dnsErr) + if dnsErr == nil || *dnsErr != expectedErr { + t.Errorf("%v: Lookup%v: unexpected error: %v", i, testName, err) + } + break + } + if err != nil { + t.Errorf("%v: Lookup%v: unexpected error: %v", i, testName, err) + } + } + } +}