Fix obsure crash in Corefile parsing (#4637)

This was found by fuzzing.

We need to make this a fully qualified domain name to catch all errors
in dnsserver/register.go and not later when plugin.Normalize() is called again on these
strings, with the prime difference being that the domain name is fully
qualified. This was found by fuzzing where "ȶ" is deemed OK, but "ȶ." is
not (might be a bug in miekg/dns actually). But here we were checking ȶ,
which is OK, and later we barf in ȶ. leading to "index out of range".

Added a tests and check manually if it would crash with the current code
(yes), and fail with an error in this PR (yes).

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben 2021-05-19 19:38:37 +02:00 committed by GitHub
parent df736adbc8
commit 5d80a6e21e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 1 deletions

View file

@ -66,6 +66,17 @@ func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddy
for ik, k := range s.Keys { for ik, k := range s.Keys {
trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme. trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme.
hosts, port, err := plugin.SplitHostPort(k1) hosts, port, err := plugin.SplitHostPort(k1)
// We need to make this a fully qualified domain name to catch all errors here and not later when
// plugin.Normalize is called again on these strings, with the prime difference being that the domain
// name is fully qualified. This was found by fuzzing where "ȶ" is deemed OK, but "ȶ." is not (might be a
// bug in miekg/dns actually). But here we were checking ȶ, which is OK, and later we barf in ȶ. leading to
// "index out of range".
for ih := range hosts {
_, _, err := plugin.SplitHostPort(dns.Fqdn(hosts[ih]))
if err != nil {
return nil, err
}
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -132,7 +132,11 @@ func OriginsFromArgsOrServerBlock(args, serverblock []string) []string {
} }
s := []string{} s := []string{}
for i := range args { for i := range args {
s = append(s, Host(args[i]).Normalize()...) sx := Host(args[i]).Normalize()
if len(sx) == 0 {
continue // silently ignores errors.
}
s = append(s, sx...)
} }
return s return s

17
test/corefile_test.go Normal file
View file

@ -0,0 +1,17 @@
package test
import (
"testing"
)
func TestCorefile1(t *testing.T) {
corefile := `ȶ
acl
`
// this crashed, now it should return an error.
i, _, _, err := CoreDNSServerAndPorts(corefile)
if err == nil {
defer i.Stop()
t.Fatalf("Expected an error got none")
}
}