From 5ea559cd34df4b7265c45e11ae01584da80c9b02 Mon Sep 17 00:00:00 2001 From: Jonathan Nobels Date: Fri, 26 Apr 2024 14:22:05 -0400 Subject: [PATCH] ipn/ipnlocal: fix null dereference for early suggested exit node queries Fixes tailscale/corp#19558 A request for the suggested exit nodes that occurs too early in the VPN lifecycle would result in a null deref of the netmap and/or the netcheck report. This checks both and errors out. Signed-off-by: Jonathan Nobels --- ipn/ipnlocal/local.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 5ab0c05ac..532ba499b 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -6253,6 +6253,7 @@ func mayDeref[T any](p *T) (v T) { } var ErrNoPreferredDERP = errors.New("no preferred DERP, try again later") +var ErrCannotSuggestExitNode = errors.New("unable to suggest an exit node, try again later") // SuggestExitNode computes a suggestion based on the current netmap and last netcheck report. If // there are multiple equally good options, one is selected at random, so the result is not stable. To be @@ -6266,6 +6267,9 @@ func (b *LocalBackend) SuggestExitNode() (response apitype.ExitNodeSuggestionRes lastReport := b.MagicConn().GetLastNetcheckReport(b.ctx) netMap := b.netMap b.mu.Unlock() + if lastReport == nil || netMap == nil { + return response, ErrCannotSuggestExitNode + } seed := time.Now().UnixNano() r := rand.New(rand.NewSource(seed)) return suggestExitNode(lastReport, netMap, r)