From 52a19b5970f36ccb10a63592d81097b2b07d9138 Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Mon, 4 Sep 2023 11:22:56 -0700 Subject: [PATCH] ipn/ipnlocal: prevent cc leaks on multiple Start calls If Start was called multiple times concurrently, it would create a new client and shutdown the previous one. However there was a race possible between shutting down the old one and assigning a new one where the concurent goroutine may have assigned another one already and it would leak. Updates tailscale/corp#14471 Signed-off-by: Maisem Ali --- ipn/ipnlocal/local.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 4e559f6d0..69bba760f 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -1470,6 +1470,13 @@ func (b *LocalBackend) Start(opts ipn.Options) error { } b.mu.Lock() + // Even though we reset b.cc above, we might have raced with + // another Start() call. If so, shut down the previous one again + // as we do not know if it was created with the same options. + prevCC = b.resetControlClientLocked() + if prevCC != nil { + defer prevCC.Shutdown() // must be called after b.mu is unlocked + } b.cc = cc b.ccAuto, _ = cc.(*controlclient.Auto) endpoints := b.endpoints