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

Change-Id: Ibe683bd6b47333a8ff30909fb2680ec8e10696ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/332094
Trust: Roland Shoemaker <roland@golang.org>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
Roland Shoemaker 2021-06-30 14:28:18 -07:00
parent 877688c838
commit 03761ede02
2 changed files with 43 additions and 1 deletions

View file

@ -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])
}
}

View file

@ -500,7 +500,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}
}
}