aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2017-06-01 12:33:40 +0100
committerGravatar GitHub <noreply@github.com> 2017-06-01 12:33:40 +0100
commit30ecb83dce02491a22eb64674354dbd9b1fa08c7 (patch)
tree98fc9d813a6df9f33b40112b7c2ae1d2b2bfad78
parente261ac1a6e64077e288ca95fbb805c9ce7aafba0 (diff)
downloadcoredns-30ecb83dce02491a22eb64674354dbd9b1fa08c7.tar.gz
coredns-30ecb83dce02491a22eb64674354dbd9b1fa08c7.tar.zst
coredns-30ecb83dce02491a22eb64674354dbd9b1fa08c7.zip
middleware/secondary: fix crash with no zone (#680)
When CoreDNS starts up and can't get a zone transfer going the Apex is empty. This `nil` is then transformed into wireformat, which fails with a nil pointer dereference in Go DNS. In this case we should just return SERVFAIL, because we don't have any info (yet). Note the lookup code returned NXDOMAIN, which is correct from a lookup standpoint, but also invalidates every name in the future loaded zone. Anyway, look for an apex before doing the lookup and return SERVFAIL if nothing is found. Fixes #679
-rw-r--r--middleware/file/lookup.go8
-rw-r--r--test/secondary_test.go47
2 files changed, 55 insertions, 0 deletions
diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go
index 2e95e42c7..9c5d95b06 100644
--- a/middleware/file/lookup.go
+++ b/middleware/file/lookup.go
@@ -39,6 +39,14 @@ func (z *Zone) Lookup(state request.Request, qname string) ([]dns.RR, []dns.RR,
}
}()
+ // If z is a secondary zone we might not have transfered it, meaning we have
+ // all zone context setup, except the actual record. This means (for one thing) the apex
+ // is empty and we don't have a SOA record.
+ soa := z.Apex.SOA
+ if soa == nil {
+ return nil, nil, nil, ServerFailure
+ }
+
if qtype == dns.TypeSOA {
return z.soa(do), z.ns(do), nil, Success
}
diff --git a/test/secondary_test.go b/test/secondary_test.go
new file mode 100644
index 000000000..dbf410047
--- /dev/null
+++ b/test/secondary_test.go
@@ -0,0 +1,47 @@
+package test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ "github.com/coredns/coredns/middleware/proxy"
+ "github.com/coredns/coredns/middleware/test"
+ "github.com/coredns/coredns/request"
+
+ "github.com/miekg/dns"
+)
+
+func TestEmptySecondaryZone(t *testing.T) {
+ // Corefile that fails to transfer example.org.
+ corefile := `example.org:0 {
+ secondary {
+ transfer from 127.0.0.1:1717
+ }
+ }
+`
+
+ i, err := CoreDNSServer(corefile)
+ if err != nil {
+ t.Fatalf("Could not get CoreDNS serving instance: %s", err)
+ }
+
+ udp, _ := CoreDNSServerPorts(i, 0)
+ if udp == "" {
+ t.Fatal("Could not get UDP listening port")
+ }
+ defer i.Stop()
+
+ log.SetOutput(ioutil.Discard)
+
+ p := proxy.NewLookup([]string{udp})
+ state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)}
+
+ resp, err := p.Lookup(state, "www.example.org.", dns.TypeA)
+ if err != nil {
+ t.Fatal("Expected to receive reply, but didn't")
+ }
+ if resp.Rcode != dns.RcodeServerFailure {
+ t.Fatalf("Expected reply to be a SERVFAIL, got %d", resp.Rcode)
+ }
+}