Skip to content

fix data race in Options.clone()#3739

Merged
ndyakov merged 2 commits into
redis:masterfrom
rubensayshi:race-opt
Mar 19, 2026
Merged

fix data race in Options.clone()#3739
ndyakov merged 2 commits into
redis:masterfrom
rubensayshi:race-opt

Conversation

@rubensayshi

@rubensayshi rubensayshi commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

we're hitting this race detected issue during testing with recent version of go-redis.

==================
WARNING: DATA RACE
Read at 0x00c0001db420 by goroutine 22:
  github.com/redis/go-redis/v9.(*Options).clone()
      /Users/ruben/work/go-redis/options.go:423 +0xf4
  github.com/redis/go-redis/v9.TestOptionsCloneMaintNotificationsRace.func2()
      /Users/ruben/work/go-redis/options_test.go:433 +0x9c

Previous write at 0x00c0001db420 by goroutine 21:
  github.com/redis/go-redis/v9.TestOptionsCloneMaintNotificationsRace.func1()
      /Users/ruben/work/go-redis/options_test.go:423 +0x160```
      
in various places `optLock` is already used to guard against this, except when doing `opt.clone()`, so wrapping that as well should fix the issue 

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches core client option cloning used in transactions/timeouts by adding locking; low functional change but could affect concurrency/performance or introduce lock contention if misused.
> 
> **Overview**
> Fixes a detected data race between `initConn` mutating `MaintNotificationsConfig.Mode` and concurrent `Options.clone()` calls by introducing `baseClient.cloneOpt()` that clones options under `optLock`.
> 
> Updates `withTimeout` and `Client.newTx()` to use the new locked clone path, and adds a `-race` regression test that concurrently toggles maintnotifications mode while cloning options.
> 
> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 384c4f66107c2bf0c4c509ea1866c26c3394a61c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Ruben de Vries and others added 2 commits March 17, 2026 16:26
…sConfig write

Demonstrates a data race where Options.clone() reads MaintNotificationsConfig
without acquiring optLock while initConn writes to it concurrently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…g write

Add baseClient.cloneOpt() that acquires optLock.RLock before cloning options,
preventing a race with initConn which writes MaintNotificationsConfig.Mode
under the same lock. Update withTimeout and newTx to use cloneOpt().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jit-ci

jit-ci Bot commented Mar 17, 2026

Copy link
Copy Markdown

Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset.

In case there are security findings, they will be communicated to you as a comment inside the PR.

Hope you’ll enjoy using Jit.

Questions? Comments? Want to learn more? Get in touch with us.

@ndyakov ndyakov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Interesting finding, i do not think there should be a race here, but trusting the detector :)

@ndyakov ndyakov added the bug label Mar 18, 2026
@ndyakov ndyakov merged commit 9aebc97 into redis:master Mar 19, 2026
78 of 81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants