Commit 273d946e authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

[release-branch.go1.12] net: avoid an infinite loop in LookupAddr

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 #34661
Updates #34660

Change-Id: Ib5e5263243bc34b9e2f85aa2b913c9cd50dbcaa5
Reviewed-on: https://go-review.googlesource.com/c/go/+/198497
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
parent 2af114ab
...@@ -738,6 +738,14 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, erro ...@@ -738,6 +738,14 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, erro
} }
} }
if h.Type != dnsmessage.TypePTR { if h.Type != dnsmessage.TypePTR {
err := p.SkipAnswer()
if err != nil {
return nil, &DNSError{
Err: "cannot marshal DNS message",
Name: addr,
Server: server,
}
}
continue continue
} }
ptr, err := p.PTRResource() ptr, err := p.PTRResource()
......
...@@ -1621,3 +1621,50 @@ func TestTXTRecordTwoStrings(t *testing.T) { ...@@ -1621,3 +1621,50 @@ func TestTXTRecordTwoStrings(t *testing.T) {
t.Errorf("txt[1], got %q, want %q", txt[1], want) t.Errorf("txt[1], got %q, want %q", txt[1], want)
} }
} }
// 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: 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)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment