Skip to content
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

Race condition in secureModule #123

Closed
viktordick opened this issue Mar 25, 2022 · 4 comments · Fixed by #125
Closed

Race condition in secureModule #123

viktordick opened this issue Mar 25, 2022 · 4 comments · Fixed by #125

Comments

@viktordick
Copy link
Contributor

BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)

In a Zope environment that includes Products.PythonScripts which use import, we sometimes see the following error message right after startup of an instance:

...
    Module AccessControl.ZopeGuards, line 422, in guarded_import
    Module AccessControl.ZopeGuards, line 483, in load_module
    Module AccessControl.SecurityInfo, line 273, in secureModule

KeyError: 'perfact.zodbsync'

As far as I understand, this is a race condition when multiple requests run into the same initializing script which imports the same library. They land on different threads of the same Zope instance, and all of them execute the following code snippet from SecurityInfo.py:

    modsec = _moduleSecurity.get(mname, None)
    if modsec is None:
        if mname in _appliedModuleSecurity:
            return sys.modules[mname]
        return  # no MSI, no module

    if imp:
        __import__(mname, *imp)
    del _moduleSecurity[mname]

That is, both threads try to import the module, add it to _moduleSecurity and both threads try to execute the del statement, but only one of them succeds.

Not sure how to fix this, maybe a simple wrapping with try except?

What I did:

Installed Zope 5.4 with Products.PythonScripts and added a script that imports a module. Started the instance, which by default starts four threads, and run two simultaneous requests that both target the script.

What I expect to happen:

Both requests should finish independently.

What actually happened:

One of them fails with the above traceback.

What version of Python and Zope/Addons I am using:

Zope 5.4, Products.PythonScripts 4.13

@d-maurer
Copy link
Contributor

d-maurer commented Mar 25, 2022 via email

@viktordick
Copy link
Contributor Author

Yes, I am and can do it. I was simply unsure if this is the right fix or if we need some more elaborate mutex or something like that. But I guess this should be enough.

@dataflake
Copy link
Member

It would be great to have a unit test that proves the problem to go with the fix

@viktordick
Copy link
Contributor Author

Yes, that's why it takes more than 5 minutes ;) Almost ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants