]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.13] net: avoid an infinite loop in LookupAddr
authorMichael Hendricks <michael@ndrix.org>
Wed, 2 Oct 2019 15:30:51 +0000 (09:30 -0600)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 3 Oct 2019 02:07:28 +0000 (02:07 +0000)
If a request for a PTR record returned a response with a non-PTR
answer, goLookupPTR would loop forever.  Skipping non-PTR answers
guarantees progress through the DNS response.

Fixes #34662
Updates #34660

Change-Id: I56f9d21e5342d07e7d843d253267e93a29707904
Reviewed-on: https://go-review.googlesource.com/c/go/+/198460
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit f0e940ebc985661f54d31c8d9ba31a553b87041b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/198489
Reviewed-by: Michael Hendricks <michael@ndrix.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
src/net/dnsclient_unix.go
src/net/dnsclient_unix_test.go

index e0a7ef855216224c7865ece76771e208c93f1198..c90892b83302e99c304f2b1863d11579767fb6f0 100644 (file)
@@ -765,6 +765,14 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, erro
                        }
                }
                if h.Type != dnsmessage.TypePTR {
+                       err := p.SkipAnswer()
+                       if err != nil {
+                               return nil, &DNSError{
+                                       Err:    "cannot marshal DNS message",
+                                       Name:   addr,
+                                       Server: server,
+                               }
+                       }
                        continue
                }
                ptr, err := p.PTRResource()
index 98304d36eab2d945ac51722a5f6d09f3da6cff2c..31cb6f721a9afffcf31309c0da14e6a28399aff3 100644 (file)
@@ -1753,3 +1753,50 @@ func TestDNSUseTCP(t *testing.T) {
                t.Fatal("exchange failed:", err)
        }
 }
+
+// Issue 34660: PTR response with non-PTR answers should ignore non-PTR
+func TestPTRandNonPTR(t *testing.T) {
+       fake := fakeDNSServer{
+               rh: func(n, _ 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:  dnsmessage.TypePTR,
+                                                       Class: dnsmessage.ClassINET,
+                                               },
+                                               Body: &dnsmessage.PTRResource{
+                                                       PTR: dnsmessage.MustNewName("golang.org."),
+                                               },
+                                       },
+                                       {
+                                               Header: dnsmessage.ResourceHeader{
+                                                       Name:  q.Questions[0].Name,
+                                                       Type:  dnsmessage.TypeTXT,
+                                                       Class: dnsmessage.ClassINET,
+                                               },
+                                               Body: &dnsmessage.TXTResource{
+                                                       TXT: []string{"PTR 8 6 60 ..."}, // fake RRSIG
+                                               },
+                                       },
+                               },
+                       }
+                       return r, nil
+               },
+       }
+       r := Resolver{PreferGo: true, Dial: fake.DialContext}
+       names, err := r.lookupAddr(context.Background(), "192.0.2.123")
+       if err != nil {
+               t.Fatalf("LookupAddr: %v", err)
+       }
+       if want := []string{"golang.org."}; !reflect.DeepEqual(names, want) {
+               t.Errorf("names = %q; want %q", names, want)
+       }
+}