From 0579cf14060179a51300c157f3952528a6d25997 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Wed, 30 Jun 2021 14:28:18 -0700 Subject: [PATCH] [release-branch.go1.15] net: don't reject null mx records Bypass hostname validity checking when a null mx record is returned as, defined in RFC 7505. Updates #46979 Updates #47012 Change-Id: Ibe683bd6b47333a8ff30909fb2680ec8e10696ef Reviewed-on: https://go-review.googlesource.com/c/go/+/332094 Trust: Roland Shoemaker Trust: Katie Hockman Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Reviewed-by: Katie Hockman (cherry picked from commit 03761ede028d811dd7d7cf8a2690d4bfa2771d85) Reviewed-on: https://go-review.googlesource.com/c/go/+/332372 Run-TryBot: Katie Hockman --- src/net/dnsclient_unix_test.go | 40 ++++++++++++++++++++++++++++++++++ src/net/lookup.go | 4 +++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index f646629912..f0f6e577ad 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1957,3 +1957,43 @@ func TestCVE202133195(t *testing.T) { t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected) } } + +func TestNullMX(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.TypeMX, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.MXResource{ + MX: dnsmessage.MustNewName("."), + }, + }, + }, + } + return r, nil + }, + } + r := Resolver{PreferGo: true, Dial: fake.DialContext} + rrset, err := r.LookupMX(context.Background(), "golang.org") + if err != nil { + t.Fatalf("LookupMX: %v", err) + } + if want := []*MX{&MX{Host: "."}}; !reflect.DeepEqual(rrset, want) { + records := []string{} + for _, rr := range rrset { + records = append(records, fmt.Sprintf("%v", rr)) + } + t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0]) + } +} diff --git a/src/net/lookup.go b/src/net/lookup.go index 0660268249..01c81dbaaf 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -488,7 +488,9 @@ func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) { if mx == nil { continue } - if !isDomainName(mx.Host) { + // Bypass the hostname validity check for targets which contain only a dot, + // as this is used to represent a 'Null' MX record. + if mx.Host != "." && !isDomainName(mx.Host) { return nil, &DNSError{Err: "MX target is invalid", Name: name} } }