-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessing attributes of a lazily-loaded module is not thread-safe #114763
Labels
Comments
effigies
added a commit
to effigies/cpython
that referenced
this issue
Jan 31, 2024
effigies
added a commit
to effigies/cpython
that referenced
this issue
Jan 31, 2024
effigies
added a commit
to effigies/cpython
that referenced
this issue
Feb 5, 2024
effigies
added a commit
to effigies/cpython
that referenced
this issue
Feb 5, 2024
brettcannon
pushed a commit
that referenced
this issue
Feb 24, 2024
…H-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock.
miss-islington
pushed a commit
to miss-islington/cpython
that referenced
this issue
Feb 24, 2024
…aces (pythonGH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock. (cherry picked from commit 200271c) Co-authored-by: Chris Markiewicz <[email protected]>
miss-islington
pushed a commit
to miss-islington/cpython
that referenced
this issue
Feb 24, 2024
…aces (pythonGH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock. (cherry picked from commit 200271c) Co-authored-by: Chris Markiewicz <[email protected]>
This was referenced Feb 24, 2024
Merged
brettcannon
pushed a commit
that referenced
this issue
Feb 26, 2024
…races (GH-114781) (GH-115870) gh-114763: Protect lazy loading modules from attribute access races (GH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock. (cherry picked from commit 200271c) Co-authored-by: Chris Markiewicz <[email protected]>
brettcannon
pushed a commit
that referenced
this issue
Feb 26, 2024
…races (GH-114781) (GH-115871) gh-114763: Protect lazy loading modules from attribute access races (GH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock. (cherry picked from commit 200271c) Co-authored-by: Chris Markiewicz <[email protected]>
woodruffw
pushed a commit
to woodruffw-forks/cpython
that referenced
this issue
Mar 4, 2024
…aces (pythonGH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock.
diegorusso
pushed a commit
to diegorusso/cpython
that referenced
this issue
Apr 17, 2024
…aces (pythonGH-114781) Setting the __class__ attribute of a lazy-loading module to ModuleType enables other threads to attempt to access attributes before the loading is complete. Now that is protected by a lock.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bug report
Bug description:
Attempting to access an attribute of a lazily-loaded module causes the module's
__class__
to be reset before its attributes have been populated.The issue is here:
cpython/Lib/importlib/util.py
Lines 168 to 177 in 6de8aa3
When attempting to access an attribute, the module's
__dict__
is not updated until after__class__
is reset. If other threads attempt to access between these two points, then an attribute lookup can fail.Assuming this is considered a bug, the two fixes I can think of are:
__getattribute__
's critical section. Theself.__class__ = type.ModuleType
would need to be moved below__dict__.update()
, which in turn would mean thatself.__spec__
andself.__dict__
would need to change toobject.__getattribute__(self, ...)
lookups to avoid recursion._LazyModule
. Here, additional work would be needed to remove no-longer-needed locks without creating another critical section where a thread enters_LazyModule.__getattribute__
but looks up its lock after it is removed by the first thread.My suspicion is that one lock is enough, so I would suggest going with 1.
CPython versions tested on:
3.8, 3.10, 3.11, 3.12
Operating systems tested on:
Linux
Linked PRs
The text was updated successfully, but these errors were encountered: