From b5df2540e3e2ceb02a4ab9449e6df5217475b29e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Sep 2026 10:41:44 +0200 Subject: [PATCH] host: guard discoverd config setup in SetDefaultEnv to fix data race SetDefaultEnv wrote discoverdClient and closed discoverdConfigured outside of the envMtx lock. If SetDefaultEnv were called concurrently with the DISCOVERD key, this could race on discoverdClient and, more critically, panic on a double close of the channel. Serialize the DISCOVERD handling under envMtx and track whether the channel has already been closed so it is only closed once. --- host/libcontainer_backend.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/host/libcontainer_backend.go b/host/libcontainer_backend.go index 3c8871438..b3f6d6fe8 100755 --- a/host/libcontainer_backend.go +++ b/host/libcontainer_backend.go @@ -164,8 +164,12 @@ type LibcontainerBackend struct { envMtx sync.RWMutex defaultEnv map[string]string - discoverdConfigured chan struct{} - networkConfigured chan struct{} + // discoverdConfigured is closed once discoverd has been configured via + // SetDefaultEnv. discoverdConfiguredSet is guarded by envMtx and tracks + // whether the channel has already been closed to prevent a double close. + discoverdConfigured chan struct{} + discoverdConfiguredSet bool + networkConfigured chan struct{} globalStateMtx sync.Mutex globalState *libcontainerGlobalState @@ -419,11 +423,14 @@ func (l *LibcontainerBackend) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, func (l *LibcontainerBackend) SetDefaultEnv(k, v string) { l.envMtx.Lock() + defer l.envMtx.Unlock() l.defaultEnv[k] = v - l.envMtx.Unlock() if k == "DISCOVERD" { l.discoverdClient = discoverd.NewClientWithURL(v) - close(l.discoverdConfigured) + if !l.discoverdConfiguredSet { + l.discoverdConfiguredSet = true + close(l.discoverdConfigured) + } } }