Skip to content

Commit

Permalink
net: avoid an infinite loop in LookupAddr
Browse files Browse the repository at this point in the history
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 #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>
  • Loading branch information
mndrix authored and bradfitz committed Oct 2, 2019
1 parent e85ffec commit f0e940e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/net/dnsclient_unix.go
Expand Up @@ -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()
Expand Down
47 changes: 47 additions & 0 deletions src/net/dnsclient_unix_test.go
Expand Up @@ -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)
}
}

0 comments on commit f0e940e

Please sign in to comment.