mirror of
https://github.com/coredns/coredns.git
synced 2026-10-08 19:45:21 -04:00
plugin/file: return SERVFAIL on self-referential CNAME loops (#8475)
A CNAME whose target is its own owner name is chased by externalLookup until the depth cap, appending the same record on every pass. The reply was NOERROR with the CNAME repeated ten times. Self-referential DNAME already returns SERVFAIL, as do wildcard CNAME loops. Return SERVFAIL here too. The check runs on the CNAME chase path only, so normal responses are unaffected. Fixes #6421 Signed-off-by: baltasarblanco <baltablanco9008@gmail.com>
This commit is contained in:
@@ -385,6 +385,11 @@ func (z *Zone) externalLookup(ctx context.Context, state request.Request, tr *tr
|
|||||||
Redo:
|
Redo:
|
||||||
cname := elem.Type(dns.TypeCNAME)
|
cname := elem.Type(dns.TypeCNAME)
|
||||||
if len(cname) > 0 {
|
if len(cname) > 0 {
|
||||||
|
// A CNAME that points to its own owner name can only loop.
|
||||||
|
if dns.CanonicalName(cname[0].Header().Name) == dns.CanonicalName(cname[0].(*dns.CNAME).Target) {
|
||||||
|
return nil, nil, nil, ServerFailure
|
||||||
|
}
|
||||||
|
|
||||||
rrs = append(rrs, cname...)
|
rrs = append(rrs, cname...)
|
||||||
|
|
||||||
if do {
|
if do {
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ a.example.com. 500 IN CNAME b.example.com.
|
|||||||
alias.example.com. 500 IN DNAME alias.example.com.
|
alias.example.com. 500 IN DNAME alias.example.com.
|
||||||
redirect.example.com. 500 IN DNAME target.example.com.
|
redirect.example.com. 500 IN DNAME target.example.com.
|
||||||
www.target.example.com. 500 IN A 192.0.2.1
|
www.target.example.com. 500 IN A 192.0.2.1
|
||||||
*.foo.example.com. 500 IN CNAME bar.foo.example.com.`
|
*.foo.example.com. 500 IN CNAME bar.foo.example.com.
|
||||||
|
self.example.com. 500 IN CNAME self.example.com.
|
||||||
|
c.example.com. 500 IN CNAME d.example.com.
|
||||||
|
d.example.com. 500 IN CNAME d.example.com.`
|
||||||
|
|
||||||
func TestFileLoop(t *testing.T) {
|
func TestFileLoop(t *testing.T) {
|
||||||
name, rm, err := test.TempFile(".", loopDB)
|
name, rm, err := test.TempFile(".", loopDB)
|
||||||
@@ -43,6 +46,8 @@ func TestFileLoop(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"wildcard CNAME", "something.foo.example.com.", dns.RcodeServerFailure, false, nil},
|
{"wildcard CNAME", "something.foo.example.com.", dns.RcodeServerFailure, false, nil},
|
||||||
{"self-referential DNAME", "www.alias.example.com.", dns.RcodeServerFailure, true, nil},
|
{"self-referential DNAME", "www.alias.example.com.", dns.RcodeServerFailure, true, nil},
|
||||||
|
{"self-referential CNAME", "self.example.com.", dns.RcodeServerFailure, true, nil},
|
||||||
|
{"CNAME chain into self-referential CNAME", "c.example.com.", dns.RcodeServerFailure, true, nil},
|
||||||
{"non-looping DNAME", "www.redirect.example.com.", dns.RcodeSuccess, true, []uint16{dns.TypeDNAME, dns.TypeCNAME, dns.TypeA}},
|
{"non-looping DNAME", "www.redirect.example.com.", dns.RcodeSuccess, true, []uint16{dns.TypeDNAME, dns.TypeCNAME, dns.TypeA}},
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
|
|||||||
Reference in New Issue
Block a user