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

Multiprocessing UNIX socket connection: client freeze if authkey is an empty byte string #88118

Closed
anon01 mannequin opened this issue Apr 27, 2021 · 4 comments
Closed
Labels
3.11 only security fixes stdlib Python modules in the Lib dir topic-multiprocessing type-bug An unexpected behavior, bug, or error

Comments

@anon01
Copy link
Mannequin

anon01 mannequin commented Apr 27, 2021

BPO 43952
Nosy @miguendes
PRs
  • bpo-43952: Fix multiprocessing Listener authkey bug #25845
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2021-04-27.11:45:15.510>
    labels = ['type-bug', 'library', '3.11']
    title = 'Multiprocessing UNIX socket connection: client freeze if authkey is an empty byte string'
    updated_at = <Date 2021-05-13.21:12:02.688>
    user = 'https://bugs.python.org/anon01'

    bugs.python.org fields:

    activity = <Date 2021-05-13.21:12:02.688>
    actor = 'pitrou'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-04-27.11:45:15.510>
    creator = 'anon01'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 43952
    keywords = ['patch']
    message_count = 3.0
    messages = ['392056', '392591', '392790']
    nosy_count = 1.0
    nosy_names = ['miguendes']
    pr_nums = ['25845']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue43952'
    versions = ['Python 3.11']

    Linked PRs

    @anon01
    Copy link
    Mannequin Author

    anon01 mannequin commented Apr 27, 2021

    When I run this code (on a UNIX system with temporary directory /tmp/):

    from multiprocessing import connection
    import threading
    key=b"1"
    
    def run():
        c=connection.Client("/tmp/xxx", authkey=key)
        c.send("data")
    
    l=connection.Listener("/tmp/xxx", authkey=key)
    threading.Thread(target=run).start()
    c=l.accept()
    print("receive", c.recv())
    

    it prints out "receive data" normally.

    However, in the special case that key=b"" the doesn't print anything, and can only be interrupted with Ctrl+C.

    key=None doesn't have that issue.

    Note that this issue does happen when the client uses the key b"" and the server uses the key None, but the program works normally if the reverse situation.

    Python version: Python 3.9.3.

    @anon01 anon01 mannequin added 3.9 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Apr 27, 2021
    @miguendes
    Copy link
    Mannequin

    miguendes mannequin commented May 1, 2021

    I tried debugging this and from what I can see it's because there's an if that checks if the authkey is not None in the Client constructor:

    https://github.com/python/cpython/blob/v3.9.4/Lib/multiprocessing/connection.py#L512

        if authkey is not None:
            answer_challenge(c, authkey)
            deliver_challenge(c, authkey)
    

    Whereas in the Listener, the check is different:

    https://github.com/python/cpython/blob/v3.9.4/Lib/multiprocessing/connection.py#L469

            c = self._listener.accept()
            if self._authkey:
                deliver_challenge(c, self._authkey)
                answer_challenge(c, self._authkey)
            return c
    

    If I change the Listener to:

            if self._authkey is not None:
                deliver_challenge(c, self._authkey)
                answer_challenge(c, self._authkey)
            return c
    

    it works.

    The docs say:

    """
    If authkey is given and not None, it should be a byte string and will be used as the secret key for an HMAC-based authentication challenge. No authentication is done if authkey is None. AuthenticationError is raised if authentication fails. See Authentication keys.
    """

    Now the question is, if None is OK because no auth will be done what about empty bytes? Can it be used as secret key? If empty bytes is not accepted shouldn't Listener/Client raise an exception in the constructor?

    @miguendes
    Copy link
    Mannequin

    miguendes mannequin commented May 3, 2021

    I had a look at the HMAC RFC and apparently empty bytes sequence can be used as secret key.

    "The definition of HMAC requires a cryptographic hash function, which
    we denote by H, and a secret key K.

    ...

    The authentication key K can be of any length up to B, the
    block length of the hash function."

    https://tools.ietf.org/html/rfc2104.html#section-2

    Assuming that is the case, the fix would be to change the Listener to:

            if self._authkey is not None:
                deliver_challenge(c, self._authkey)
                answer_challenge(c, self._authkey)
            return c
    

    I created a PR for that, if anyone can review it, I appreciate it.
    #25845

    @pitrou pitrou added 3.11 only security fixes and removed 3.9 only security fixes labels May 13, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @gpshead
    Copy link
    Member

    gpshead commented Feb 27, 2024

    A bit of an ironic issue as using an empty key seems kind of pointless... but thanks for the edge case fix! :)

    gpshead added a commit that referenced this issue Mar 6, 2024
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by #25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 6, 2024
    …6434)
    
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by python#25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    (cherry picked from commit ea1803e)
    
    Co-authored-by: Gregory P. Smith <greg@krypto.org>
    miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 6, 2024
    …6434)
    
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by python#25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    (cherry picked from commit ea1803e)
    
    Co-authored-by: Gregory P. Smith <greg@krypto.org>
    gpshead added a commit that referenced this issue Mar 6, 2024
    …GH-116440)
    
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by #25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    (cherry picked from commit ea1803e)
    
    Co-authored-by: Gregory P. Smith <greg@krypto.org>
    gpshead added a commit that referenced this issue Mar 6, 2024
    …GH-116441)
    
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by #25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    (cherry picked from commit ea1803e)
    
    Co-authored-by: Gregory P. Smith <greg@krypto.org>
    adorilson pushed a commit to adorilson/cpython that referenced this issue Mar 25, 2024
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by python#25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    diegorusso pushed a commit to diegorusso/cpython that referenced this issue Apr 17, 2024
    Fix some test_multiprocessing flakiness.
    
    Potentially introduced by python#25845
    
    not joining that thread likely leads to recently observed "environment
    changed" logically passing but overall failing tests seen on some
    buildbots similar to:
    
    ```
    1 test altered the execution environment (env changed):
        test.test_multiprocessing_fork.test_processes
    
    2 re-run tests:
        test.test_multiprocessing_fork.test_processes
        test.test_multiprocessing_forkserver.test_processes
    ```
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 only security fixes stdlib Python modules in the Lib dir topic-multiprocessing type-bug An unexpected behavior, bug, or error
    Projects
    Development

    No branches or pull requests

    4 participants