Skip to content

gh-151644: Fix data race in sys.setdlopenflags/getdlopenflags under free-threading#151768

Merged
nascheme merged 2 commits into
python:mainfrom
zangjiucheng:gh-151644-fix
Jul 3, 2026
Merged

gh-151644: Fix data race in sys.setdlopenflags/getdlopenflags under free-threading#151768
nascheme merged 2 commits into
python:mainfrom
zangjiucheng:gh-151644-fix

Conversation

@zangjiucheng

@zangjiucheng zangjiucheng commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

In free-threading builds, concurrent calls to sys.getdlopenflags() and
sys.setdlopenflags() race on interp->imports.dlopenflags — a plain int
field read and written with no synchronisation.

Fix

Replace the bare load/store in _PyImport_GetDLOpenFlags /
_PyImport_SetDLOpenFlags with FT_ATOMIC_LOAD_INT_RELAXED /
FT_ATOMIC_STORE_INT_RELAXED.

Atomics are preferred over PyMutex (used for the analogou
because each access is a single load or store — no multi-field consistency
guarantee is needed. Relaxed ordering is correct: dlopenfl standalone config integer with no ordering relationship to other memory, consistent with how lazy_imports_modeandpystats_enable
in the same file.

…nder free-threading

In free-threading builds, concurrent calls to sys.getdlopenflags() and
sys.setdlopenflags() race on interp->imports.dlopenflags.  Fix by
using FT_ATOMIC_LOAD_INT_RELAXED / FT_ATOMIC_STORE_INT_RELAXED in
_PyImport_GetDLOpenFlags and _PyImport_SetDLOpenFlags, consistent with
how analogous interpreter-state integer fields (lazy_imports_mode,
pystats_enabled) are protected.

Relaxed ordering is correct here: dlopenflags is a standalone config
integer with no ordering relationship to other memory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nascheme nascheme merged commit cde31ec into python:main Jul 3, 2026
56 checks passed
@nascheme nascheme added needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels Jul 16, 2026
@miss-islington-app

Copy link
Copy Markdown

Thanks @zangjiucheng for the PR, and @nascheme for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington-app

Copy link
Copy Markdown

Thanks @zangjiucheng for the PR, and @nascheme for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖

@bedevere-app

bedevere-app Bot commented Jul 16, 2026

Copy link
Copy Markdown

GH-153789 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Jul 16, 2026
@bedevere-app

bedevere-app Bot commented Jul 16, 2026

Copy link
Copy Markdown

GH-153790 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jul 16, 2026
kumaraditya303 pushed a commit that referenced this pull request Jul 16, 2026
…under free-threading (gh-151768) (#153790)

gh-151644: Fix data race in sys.setdlopenflags/getdlopenflags under free-threading (gh-151768)

In free-threading builds, concurrent calls to sys.getdlopenflags() and
sys.setdlopenflags() race on interp->imports.dlopenflags.  Fix by
using FT_ATOMIC_LOAD_INT_RELAXED / FT_ATOMIC_STORE_INT_RELAXED in
_PyImport_GetDLOpenFlags and _PyImport_SetDLOpenFlags, consistent with
how analogous interpreter-state integer fields (lazy_imports_mode,
pystats_enabled) are protected.

Relaxed ordering is correct here: dlopenflags is a standalone config
integer with no ordering relationship to other memory.
(cherry picked from commit cde31ec)

Co-authored-by: Jiucheng(Oliver) <git.jiucheng@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants