From 000e842f7b86d145b3032ec18beda87d6b273272 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Thu, 12 Dec 2019 15:00:10 +0300 Subject: [PATCH 1/2] - DNS: fix deadlock in Server.ServeHTTP() s.RLock() is called again in filterResponse() while another thread holds s.Lock() --- dnsforward/dnsforward.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index 2988133d..f5963058 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -380,8 +380,11 @@ func (s *Server) Reconfigure(config *ServerConfig) error { // ServeHTTP is a HTTP handler method we use to provide DNS-over-HTTPS func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.RLock() - s.dnsProxy.ServeHTTP(w, r) + p := s.dnsProxy s.RUnlock() + if p != nil { // an attempt to protect against race in case we're here after Close() was called + p.ServeHTTP(w, r) + } } func (s *Server) beforeRequestHandler(p *proxy.Proxy, d *proxy.DNSContext) (bool, error) { From ef57f7e192fdd4fbbfe25dc1c1e61d52e9f0b6ee Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Thu, 12 Dec 2019 15:04:29 +0300 Subject: [PATCH 2/2] - DNS: fix race in WriteDiskConfig() --- dnsforward/dnsforward.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index f5963058..8027bc5b 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -86,10 +86,23 @@ func (s *Server) Close() { s.Unlock() } +func stringArrayDup(a []string) []string { + a2 := make([]string, len(a)) + copy(a2, a) + return a2 +} + // WriteDiskConfig - write configuration func (s *Server) WriteDiskConfig(c *FilteringConfig) { s.Lock() - *c = s.conf.FilteringConfig + sc := s.conf.FilteringConfig + *c = sc + c.RatelimitWhitelist = stringArrayDup(sc.RatelimitWhitelist) + c.BootstrapDNS = stringArrayDup(sc.BootstrapDNS) + c.AllowedClients = stringArrayDup(sc.AllowedClients) + c.DisallowedClients = stringArrayDup(sc.DisallowedClients) + c.BlockedHosts = stringArrayDup(sc.BlockedHosts) + c.UpstreamDNS = stringArrayDup(sc.UpstreamDNS) s.Unlock() }