ipn/ipnlocal: hold the mutex when in onTailnetDefaultAutoUpdate (#11786)

Turns out, profileManager is not safe for concurrent use and I missed
all the locking infrastructure in LocalBackend, oops.

I was not able to reproduce the race even with `go test -count 100`, but
this seems like an obvious fix.

Fixes #11773

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
irbekrm/extsvcnftableslb
Andrew Lytvynov 7 months ago committed by GitHub
parent 88a7767492
commit 22bd506129
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -2498,6 +2498,9 @@ func (b *LocalBackend) onClientVersion(v *tailcfg.ClientVersion) {
} }
func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) { func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) {
unlock := b.lockAndGetUnlock()
defer unlock()
prefs := b.pm.CurrentPrefs() prefs := b.pm.CurrentPrefs()
if !prefs.Valid() { if !prefs.Valid() {
b.logf("[unexpected]: received tailnet default auto-update callback but current prefs are nil") b.logf("[unexpected]: received tailnet default auto-update callback but current prefs are nil")
@ -2511,12 +2514,12 @@ func (b *LocalBackend) onTailnetDefaultAutoUpdate(au bool) {
b.logf("using tailnet default auto-update setting: %v", au) b.logf("using tailnet default auto-update setting: %v", au)
prefsClone := prefs.AsStruct() prefsClone := prefs.AsStruct()
prefsClone.AutoUpdate.Apply = opt.NewBool(au) prefsClone.AutoUpdate.Apply = opt.NewBool(au)
_, err := b.EditPrefs(&ipn.MaskedPrefs{ _, err := b.editPrefsLockedOnEntry(&ipn.MaskedPrefs{
Prefs: *prefsClone, Prefs: *prefsClone,
AutoUpdateSet: ipn.AutoUpdatePrefsMask{ AutoUpdateSet: ipn.AutoUpdatePrefsMask{
ApplySet: true, ApplySet: true,
}, },
}) }, unlock)
if err != nil { if err != nil {
b.logf("failed to apply tailnet-wide default for auto-updates (%v): %v", au, err) b.logf("failed to apply tailnet-wide default for auto-updates (%v): %v", au, err)
return return

Loading…
Cancel
Save