]> Cypherpunks repositories - gostls13.git/commitdiff
net: discard unrooted 254 byte names, not rooted ones
authorMateusz Poliwczak <mpoliwczak34@gmail.com>
Sat, 6 Aug 2022 05:42:25 +0000 (05:42 +0000)
committerDamien Neil <dneil@google.com>
Thu, 11 Aug 2022 18:25:36 +0000 (18:25 +0000)
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 <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go

index 088c81adee92777d43845bfc1a601354de5d5648..cc0bf244eab34cd84682b6ca901ae61e9b10ba1f 100644 (file)
@@ -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
        }
 
index 415c53e1e7826c73dbad7f9adfdd9a7552934155..17798e434b146f70b8aeb080796a799cbf8d2523 100644 (file)
@@ -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)
+                       }
+               }
+       }
+}