Skip to content

gh-152754: Fix crash when an os.scandir iterator is shared between threads - #153462

Merged
nascheme merged 10 commits into
python:mainfrom
nascheme:gh-152754-os-race-mutex
Aug 21, 2026
Merged

nascheme merged 10 commits into
python:mainfrom
nascheme:gh-152754-os-race-mutex

Conversation

@nascheme

@nascheme nascheme commented Jul 9, 2026 •

Copy link
Copy Markdown
Member

The issue was a race between ScandirIterator_iternext() and ScandirIterator.close(): one thread could be inside readdir() or FindNextFileW() while another closed the underlying directory stream or Windows handle.

Changes

  • Add a PyMutex and atomic closed state to ScandirIterator in all builds.
  • Serialize access to the native directory stream or handle.
  • Make close() mark the iterator closed immediately without waiting for an in-progress directory read. The reading thread performs the native close afterward when necessary.
  • Copy native directory-entry data while holding the mutex, then create Python objects and report errors after releasing it.
  • Keep Py_BEGIN_ALLOW_THREADS around readdir(), FindNextFileW(), closedir(), and FindClose().
  • Avoid incorrectly emitting ResourceWarning when opening the directory fails.
  • Add regression tests for concurrent iteration, iteration racing with close(), and failed iterator creation.
  • Document the behavior of sharing a scandir() iterator between threads.

Threading semantics

Sharing an os.scandir() iterator between threads will no longer corrupt the iterator or crash. Concurrent calls may consume entries in any order, so which thread receives each entry remains unspecified. Calling close() while another thread is iterating marks the iterator closed immediately and ends iteration early.

A PyMutex is used rather than a critical section because the protection must remain active across Py_BEGIN_ALLOW_THREADS while the native directory operation runs without the GIL.

…een threads

Co-authored-by: Neil Schemenauer <nas-github@arctrix.com>
Comment thread Modules/posixmodule.c Outdated
@read-the-docs-community

read-the-docs-community Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

@nascheme
nascheme marked this pull request as ready for review August 13, 2026 00:39
@nascheme

Copy link
Copy Markdown
Member Author

Note, I revised this PR to no longer try to be thread-safe with multiple threads using the same iterator. That seems a pretty unlikely usage scenario. Instead, this avoids crashing and/or memory corruption.

Comment thread Modules/posixmodule.c Outdated
@nascheme
nascheme merged commit 999a046 into python:main Aug 21, 2026
58 checks passed
@nascheme nascheme added needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels Oct 13, 2026
@miss-islington-app

Copy link
Copy Markdown

Thanks @nascheme for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

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

@miss-islington-app

Copy link
Copy Markdown

Sorry, @nascheme, I could not cleanly backport this to 3.14 due to a conflict.

Please backport manually with cherry_picker, see the devguide for more information.

cherry_picker 999a046b24cff4ba0e72b574196721f66bd08237 3.14

@bedevere-app

bedevere-app Bot commented Oct 13, 2026

Copy link
Copy Markdown

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

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Oct 13, 2026
nascheme added a commit that referenced this pull request Oct 13, 2026
…ween threads (gh-153462) (gh-159365)

(cherry picked from commit 999a046)

Co-authored-by: Neil Schemenauer <nas-github@arctrix.com>
Co-authored-by: Timofey Ivankov <playboicartina@gmail.com>
@bedevere-app

bedevere-app Bot commented Oct 13, 2026

Copy link
Copy Markdown

GH-159381 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 Oct 13, 2026
@nascheme
nascheme deleted the gh-152754-os-race-mutex branch October 13, 2026 23:30
nascheme added a commit that referenced this pull request Oct 14, 2026
…ween threads (gh-153462) (gh-159381)

(cherry picked from commit 999a046)

Co-authored-by: Timofey Ivankov <playboicartina@gmail.com>
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.

3 participants