@marcel91200 / caddy Mirror · read-only / commits / 325c244e
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 11:00 UTC

caddytls: fix TLS state races and ECH rotation retry (#7756)

* caddytls: fix data race in session ticket key rotation stayUpdated copies the map header (configs := s.configs) under the lock, then iterates the original map after releasing it. Concurrent calls to register/unregister mutate the same map. Hold the lock for the entire iteration instead. * caddytls: fix data race in AllMatchingCertificates AllMatchingCertificates reads the package-level certCache without acquiring certCacheMu, while Cleanup sets certCache to nil under the write lock. The adjacent HasCertificateForSubject correctly acquires certCacheMu.RLock. Add the missing RLock/RUnlock to match. * caddytls: fix ECH key rotation stopping permanently on error When rotateECHKeys returns an error, the rotation goroutine returns immediately, stopping all future key rotation for the lifetime of the process. Change return to continue, matching the error handling for publishECHConfigs two lines below.

cbro committed May 20, 2026 at 02:35 UTC 325c244ea71a645c224afa1d0b46296ed76ef9fd
2 files changed +5 -4
modules/caddytls/sessiontickets.go
+2 -3
@@ -137,11 +137,10 @@ func (s *SessionTicketService) stayUpdated() {
137 case newKeys := <-keysChan:
138 s.mu.Lock()
139 s.currentKeys = newKeys
140 - configs := s.configs
141 - s.mu.Unlock()
142 - for cfg := range configs {
140 + for cfg := range s.configs {
141 cfg.SetSessionTicketKeys(newKeys)
142 }
143 + s.mu.Unlock()
144 case <-s.stopChan:
145 return
146 }
modules/caddytls/tls.go
+3 -1
@@ -440,7 +440,7 @@ func (t *TLS) Start() error {
440 t.EncryptedClientHello.configsMu.Unlock()
441 if err != nil {
442 echLogger.Error("rotating ECH configs failed", zap.Error(err))
443 - return
443 + continue
444 }
445 err := t.publishECHConfigs(echLogger)
446 if err != nil {
@@ -879,6 +879,8 @@ func (t *TLS) getAutomationPolicyForName(name string) *AutomationPolicy {
879 // AllMatchingCertificates returns the list of all certificates in
880 // the cache which could be used to satisfy the given SAN.
881 func AllMatchingCertificates(san string) []certmagic.Certificate {
882 + certCacheMu.RLock()
883 + defer certCacheMu.RUnlock()
884 return certCache.AllMatchingCertificates(san)
885 }
886