aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2019-10-02 20:59:27 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2019-10-03 02:07:10 +0000
commit273d946ec451a0722d21ac12494be7e367bbaac6 (patch)
tree1de6e4e5d4d50c585ccffb7a77acb02f1440c21e
parent2af114ab22fca22107a8ce5ff9742abecd41521e (diff)
downloadgo-273d946ec451a0722d21ac12494be7e367bbaac6.tar.gz
go-273d946ec451a0722d21ac12494be7e367bbaac6.zip
[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: Emmanuel Odeke <emm.odeke@gmail.com>
-rw-r--r--src/net/dnsclient_unix.go8
-rw-r--r--src/net/dnsclient_unix_test.go47
2 files changed, 55 insertions, 0 deletions
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 86ce92dc43..7f335eba9f 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -738,6 +738,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()
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index be04a44c14..f5e7992f30 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -1621,3 +1621,50 @@ func TestTXTRecordTwoStrings(t *testing.T) {
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)
+ }
+}