diff options
author | 2021-01-15 19:26:04 +0100 | |
---|---|---|
committer | 2021-01-15 18:26:04 +0000 | |
commit | 342eae9b4b1791da8fb92d36b3968839f3f38b94 (patch) | |
tree | 8ed2b47ecb8005fe68e007254dbfc355f1d2e83f /plugin/file/lookup.go | |
parent | f5f977f4c8c6e77a8908ebd9fce781a74c26374e (diff) | |
download | coredns-342eae9b4b1791da8fb92d36b3968839f3f38b94.tar.gz coredns-342eae9b4b1791da8fb92d36b3968839f3f38b94.tar.zst coredns-342eae9b4b1791da8fb92d36b3968839f3f38b94.zip |
plugin/file: guard against cname loops (#4387)
Automatically submitted.
Diffstat (limited to 'plugin/file/lookup.go')
-rw-r--r-- | plugin/file/lookup.go | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/plugin/file/lookup.go b/plugin/file/lookup.go index e036d809a..6eeb4c397 100644 --- a/plugin/file/lookup.go +++ b/plugin/file/lookup.go @@ -3,6 +3,7 @@ package file import ( "context" + "github.com/coredns/coredns/core/dnsserver" "github.com/coredns/coredns/plugin/file/rrutil" "github.com/coredns/coredns/plugin/file/tree" "github.com/coredns/coredns/request" @@ -29,7 +30,6 @@ const ( // Lookup looks up qname and qtype in the zone. When do is true DNSSEC records are included. // Three sets of records are returned, one for the answer, one for authority and one for the additional section. func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) ([]dns.RR, []dns.RR, []dns.RR, Result) { - qtype := state.QType() do := state.Do() @@ -62,6 +62,16 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) elem, wildElem *tree.Elem ) + loop, _ := ctx.Value(dnsserver.LoopKey{}).(int) + if loop > 8 { + // We're back here for the 9th time; we have a loop and need to bail out. + // Note the answer we're returning will be incomplete (more cnames to be followed) or + // illegal (wildcard cname with multiple identical records). For now it's more important + // to protect ourselves then to give the client a valid answer. We return with an error + // to let the server handle what to do. + return nil, nil, nil, ServerFailure + } + // Lookup: // * Per label from the right, look if it exists. We do this to find potential // delegation records. @@ -105,6 +115,7 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) // Only one DNAME is allowed per name. We just pick the first one to synthesize from. dname := dnamerrs[0] if cname := synthesizeCNAME(state.Name(), dname.(*dns.DNAME)); cname != nil { + ctx = context.WithValue(ctx, dnsserver.LoopKey{}, loop+1) answer, ns, extra, rcode := z.externalLookup(ctx, state, elem, []dns.RR{cname}) if do { @@ -156,6 +167,7 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) if found && shot { if rrs := elem.Type(dns.TypeCNAME); len(rrs) > 0 && qtype != dns.TypeCNAME { + ctx = context.WithValue(ctx, dnsserver.LoopKey{}, loop+1) return z.externalLookup(ctx, state, elem, rrs) } @@ -192,6 +204,7 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string) auth := ap.ns(do) if rrs := wildElem.TypeForWildcard(dns.TypeCNAME, qname); len(rrs) > 0 { + ctx = context.WithValue(ctx, dnsserver.LoopKey{}, loop+1) return z.externalLookup(ctx, state, wildElem, rrs) } |