multiprocessing.connection.Client deadlocks when trying to connect to a listener without a password
還沒有人認領這個 Issue。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 35.9k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
We set up a multiprocessing.connection.Listener with no authkey. When we try to connect to it with a Client with an authkey, the Client deadlocks. Here is a working example:
import socket
import threading
import time
from multiprocessing.connection import Client, Listener
def _test(*, listener: str | None, client: str | None) -> tuple[Exception | None, Exception | None, list]:
_autkey_listener = listener.encode() if listener else None
_authkey_client = client.encode() if client else None
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("localhost", 0))
address = s.getsockname()
thread_exc = None
thread_got = []
client_exc = None
def target() -> None:
try:
with Listener(address, authkey=_autkey_listener) as l:
c = l.accept()
while True:
value = c.recv()
if not value:
break
thread_got.append(value)
except Exception as e:
nonlocal thread_exc
thread_exc = e
t = threading.Thread(target=target)
t.start()
try:
with Client(address, authkey=_authkey_client) as c:
c.send("hello")
time.sleep(0.1)
c.send(None)
t.join()
except Exception as e:
client_exc = e
return thread_exc, client_exc, thread_got
if __name__ == "__main__":
print(" no passwords ".center(40, "-"))
print(_test(listener=None, client=None))
print(" two matching passwords ".center(40, "-"))
print(_test(listener="password", client="password"))
print(" client has wrong password ".center(40, "-"))
print(_test(listener="password", client="wrong"))
print(" client has no password ".center(40, "-"))
print(_test(listener="password", client=None))
# This is the case which deadlocks
print(" listener has no password ".center(40, "-"))
print(_test(listener=None, client="password"))
which outputs:
------------- no passwords -------------
(None, None, ['hello'])
-------- two matching passwords --------
(None, None, ['hello'])
------ client has wrong password -------
(AuthenticationError('digest received was wrong'), AuthenticationError('digest sent was rejected'), [])
-------- client has no password --------
(AuthenticationError("expected 'md5' of length 16 got 20"), None, [])
------- listener has no password -------
and then stops.
Upon some investigation, the following bit of code from Client is to blame:
if authkey is not None:
answer_challenge(c, authkey)
deliver_challenge(c, authkey)
since the listener is not configured to deliver the challenge to the connections. I think this would be resolved with an optional timeout kwarg in answer_challenge. If this suggestion is accepted I would be very happy to work on it 👍
CPython versions tested on:
3.9, 3.10, 3.11, 3.12
Operating systems tested on:
macOS, Windows
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 multiprocessing.connection.Client 和報告中識別出的 answer_challenge 路徑開始,然後使用提供的 reproducer 執行其所有驗證組合。完成的標準是 listener-without-password 和 client-with-password 情況不再掛起,同時其他報告中的情況保留其已展示的結果。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- distributed-systems, networking
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 停滯
- 描述清晰度
- 基本清楚
- 新手友好度
- 45/100