From 7e098a93a6918ce6ba6527363a566c7f9a323119 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Sep 2026 10:14:07 +0200 Subject: [PATCH] flannel: protect knownSubnets map with mutex to fix data race The package-level knownSubnets map is read and written in WatchSubnets without synchronization. Multiple goroutines calling WatchSubnets concurrently would race on this Go map, causing undefined behavior. Add a sync.Mutex to serialize access to the map. --- flannel/discoverd/registry.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flannel/discoverd/registry.go b/flannel/discoverd/registry.go index 735bfb056e..80026aebfe 100755 --- a/flannel/discoverd/registry.go +++ b/flannel/discoverd/registry.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "reflect" + "sync" "time" "github.com/flynn/flynn/discoverd/client" @@ -89,6 +90,9 @@ func (r *registry) UpdateSubnet(sn, data string, ttl uint64) (*subnet.Response, return newResponse(net), nil } +// knownSubnetsMu protects knownSubnets from concurrent access. +var knownSubnetsMu sync.Mutex + // knownSubnets is updated each time we receive a service metadata event so // that we can calculate which subnets are new and should be returned from // WatchSubnets @@ -111,6 +115,7 @@ func (r *registry) WatchSubnets(since uint64, stop chan bool) (*subnet.Response, return nil, err } subnets := make(map[string][]byte) + knownSubnetsMu.Lock() for subnet, data := range net.Subnets { if known, ok := knownSubnets[subnet]; ok && reflect.DeepEqual(known, data) { continue @@ -118,6 +123,7 @@ func (r *registry) WatchSubnets(since uint64, stop chan bool) (*subnet.Response, subnets[subnet] = []byte(*data) } knownSubnets = net.Subnets + knownSubnetsMu.Unlock() if event.ServiceMeta.Index >= since { return &subnet.Response{Subnets: subnets, Index: event.ServiceMeta.Index}, nil }