The RecordSyncFailure and ResetBackoffOnDaemonStart functions had a TOCTOU (time-of-check-time-of-use) race condition. They called LoadSyncState (which locks, reads, unlocks) then modified the state, then called SaveSyncState (which locks, writes, unlocks). Between LoadSyncState returning and SaveSyncState being called, another goroutine could load the old state, modify it, and save it - then this goroutine's save would overwrite those changes. Fix: Create internal unlocked helper functions (loadSyncStateUnlocked, saveSyncStateUnlocked) and have RecordSyncFailure and ResetBackoffOnDaemonStart hold the lock for the entire load-modify-save operation. Co-authored-by: Steven Syrek <steven.syrek@deepl.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
4.9 KiB
4.9 KiB