Skip to content

Conversation

@gpshead
Copy link
Member

@gpshead gpshead commented Jan 10, 2026

Fix race condition where a thread could receive a stale module reference when another thread's import fails. Adds verification after the "skip lock" fast path in both Python and C code paths to check if the module is still in sys.modules before returning it.

Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:

1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules

The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.

Changes:
- Lib/importlib/_bootstrap.py: Add check after fast path in _find_and_load()
- Python/import.c: Add checks in PyImport_GetModule() and
  PyImport_ImportModuleLevelObject()
- Add regression test test_import_failure_race_condition()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gpshead gpshead force-pushed the fix-import-race-condition branch from 78fed07 to 6393e97 Compare January 10, 2026 11:10
@gpshead gpshead added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes 🔨 test-with-buildbots Test PR w/ buildbots; report in status section labels Jan 10, 2026
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @gpshead for commit 0a682cd 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F143651%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jan 10, 2026
Add error checking inside the `if (mod_check != mod)` block to properly
handle the case where import_get_module itself fails with an exception.
Also refactor PyImport_GetModule to use an error label for cleanup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gpshead gpshead force-pushed the fix-import-race-condition branch from 45c02dc to 842c160 Compare January 10, 2026 21:14
@gpshead
Copy link
Member Author

gpshead commented Jan 10, 2026

the few buildbot failures in the earlier round all looked like network issues. not rerunning those.

@gpshead gpshead requested review from picnixz and pitrou January 11, 2026 18:24
@gpshead gpshead added 🔨 test-with-buildbots Test PR w/ buildbots; report in status section 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section labels Jan 11, 2026
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @gpshead for commit 102845b 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F143651%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @gpshead for commit 102845b 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F143651%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed 🔨 test-with-buildbots Test PR w/ buildbots; report in status section 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section labels Jan 11, 2026
@gpshead gpshead requested a review from picnixz January 12, 2026 07:48
@encukou encukou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Feb 4, 2026
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @encukou for commit 179d7bf 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F143651%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Feb 4, 2026
@encukou encukou merged commit ac8b5b6 into python:main Feb 10, 2026
118 of 120 checks passed
@miss-islington-app
Copy link

Thanks @gpshead for the PR, and @encukou for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Feb 10, 2026
…onGH-143651)

Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:

1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules

The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.
(cherry picked from commit ac8b5b6)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@miss-islington-app
Copy link

Sorry, @gpshead and @encukou, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker ac8b5b6890006ee7254ea878866cb486ff835ecb 3.13

@bedevere-app
Copy link

bedevere-app bot commented Feb 10, 2026

GH-144662 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 Feb 10, 2026
gpshead added a commit that referenced this pull request Feb 11, 2026
…143651) (#144662)

gh-143650: Fix importlib race condition on import failure (GH-143651)

Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:

1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules

The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.
(cherry picked from commit ac8b5b6)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
gpshead added a commit to gpshead/cpython that referenced this pull request Feb 11, 2026
…onGH-143651)

Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:

1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules

The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

cherry picked from ac8b5b6
@bedevere-app
Copy link

bedevere-app bot commented Feb 11, 2026

GH-144697 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Feb 11, 2026
gpshead added a commit that referenced this pull request Feb 11, 2026
…143651) (#144697)

gh-143650: Fix importlib race condition on import failure (GH-143651)

Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:

1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules

The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

cherry picked from ac8b5b6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants