Skip to content

Commit

Permalink
Prevent race condition in guarded_import (#125)
Browse files Browse the repository at this point in the history
Co-authored-by: Jens Vagelpohl <jens@plyp.com>
  • Loading branch information
viktordick and dataflake committed Mar 27, 2022
1 parent d699289 commit be8cd14
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ For changes before version 3.0, see ``HISTORY.rst``.
5.4 (unreleased)
----------------

- Nothing changed yet.
- Prevent race condition in guarded_import
(see `#123 <https://github.com/zopefoundation/AccessControl/issues/123>`_)


5.3 (2022-02-25)
Expand Down
7 changes: 6 additions & 1 deletion src/AccessControl/SecurityInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,15 @@ def secureModule(mname, *imp):

if imp:
__import__(mname, *imp)
del _moduleSecurity[mname]
module = sys.modules[mname]
modsec.apply(module.__dict__)
_appliedModuleSecurity[mname] = modsec
try:
del _moduleSecurity[mname]
except KeyError:
# In case of access from multiple threads, the del might fail, but that
# is OK.
pass
return module


Expand Down
19 changes: 19 additions & 0 deletions src/AccessControl/tests/testModuleSecurity.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ def testPublicModule(self):
self.assertAuth('AccessControl.tests.public_module.submodule',
('pub',))

def testPublicModuleThreaded(self):
"""
Import the same module from two threads simultaneously, checking that
this does not result in a race condition.
"""
import threading
finished = []

def threaded_run():
self.assertAuth('AccessControl.tests.public_module', ())
finished.append(True)

threads = [threading.Thread(target=threaded_run) for _ in range(2)]

[t.start() for t in threads]
[t.join() for t in threads]

self.assertEqual(len(finished), 2)

def test_public_module_asterisk_not_allowed(self):
self.assertUnauth('AccessControl.tests.public_module', ('*',))

Expand Down

0 comments on commit be8cd14

Please sign in to comment.