mirror of
https://github.com/coredns/coredns.git
synced 2025-11-01 10:43:17 -04:00
plugin/file: guard against cname loops (#4387)
Automatically submitted.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ func (u *Upstream) Lookup(ctx context.Context, state request.Request, name strin
|
||||
req.SetEdns0(uint16(size), do)
|
||||
|
||||
nw := nonwriter.New(state.W)
|
||||
|
||||
server.ServeDNS(ctx, nw, req)
|
||||
|
||||
return nw.Msg, nil
|
||||
|
||||
Reference in New Issue
Block a user