ipn/ipnlocal: avoid initPeerAPIListener crash on certain concurrent actions
We were crashing on in initPeerAPIListener when called from
authReconfig when b.netMap is nil. But authReconfig already returns
before the call to initPeerAPIListener when b.netMap is nil, but it
releases the b.mu mutex before calling initPeerAPIListener which
reacquires it and assumes it's still nil.
The only thing that can be setting it to nil is setNetMapLocked, which
is called by ResetForClientDisconnect, Logout/logout, or Start, all of
which can happen during an authReconfig.
So be more defensive.
Fixes #1996
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit ecfb2639cc
)
release-branch/1.8
parent
28a8f9c90e
commit
1cd4e11b26
|
@ -1890,6 +1890,15 @@ func (b *LocalBackend) initPeerAPIListener() {
|
|||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
if b.netMap == nil {
|
||||
// We're called from authReconfig which checks that
|
||||
// netMap is non-nil, but if a concurrent Logout,
|
||||
// ResetForClientDisconnect, or Start happens when its
|
||||
// mutex was released, the netMap could be
|
||||
// nil'ed out (Issue 1996). Bail out early here if so.
|
||||
return
|
||||
}
|
||||
|
||||
if len(b.netMap.Addresses) == len(b.peerAPIListeners) {
|
||||
allSame := true
|
||||
for i, pln := range b.peerAPIListeners {
|
||||
|
|
Loading…
Reference in New Issue