mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #4443] [Bug]: Single unauthenticated connection permanently wedges Mooncake P2P handshake daemon #1120
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#1120
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @yyymk on GitHub (Oct 1, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/4443
Bug Report
Summary
The P2P handshake daemon of mooncake-transfer-engine serves all control-plane traffic (RDMA QP setup, segment metadata exchange, notify, probe) from a single serial accept loop, and response writes have no timeout. One unauthenticated TCP connection that sends a valid request and never reads the response blocks the daemon's writer forever. The whole handshake service freezes until the engine process is restarted, while the process stays alive and health checks stay green. Runtime-confirmed on 0.3.13.post1 (latest release) and 0.3.11.post1. No fix available. Suggested severity: Medium, CVSS 6.5.
Details
SocketHandShakePlugin::startDaemon(src/transfer_metadata_plugin.cpp) handles each accepted connection inline in one listener thread: accept,readString, callback,writeString, wait for the peer to close, close. It accepts the next connection only after the previous one is fully served. There is no worker thread or pool.The accepted socket gets
SO_RCVTIMEObut neverSO_SNDTIMEO, andwriteFully(include/common.h) loops onwrite()with no deadline. If the peer stops reading, the daemon thread blocks in the kernel on a full send buffer indefinitely.The message that triggers this is a Metadata request (frame type 1). The daemon answers it with the serialized local segment descriptor (
receivePeerMetadata->encodeSegmentDesc), whose size scales with the number of registered buffers. With 60000 registered buffers the response is about 4 MB, far beyond the socket buffers of a peer that sets a smallSO_RCVBUFand never reads. Requests to this daemon are unauthenticated.There is also a read-side variant: sending only the 8-byte length header holds the daemon in
readFullyuntil its 300 s deadline on <= 0.3.12 (measured on 0.3.11.post1: probes fail for 300 s, then recover instantly). On 0.3.13 the connection is dropped after about 5 s, so only the write-side wedge above applies to current releases. It was re-verified on 0.3.13.post1.PoC
Environment: Linux x86_64, Python 3.11,
pip install mooncake-transfer-engine==0.3.13.post1. Run the victim withGLOG_logtostderr=1 MC_FORCE_TCP=1.Victim (registers many small buffers so the Metadata response is megabytes):
Attacker (one connection, then do nothing):
Probe (run repeatedly from a third shell to measure the daemon):
Observed on 0.3.13.post1: before the attack, probes answer in under 1 ms with
{"status":"success"}. While the wedge socket is open, 16/16 probes over a 10 minute window timed out, the victim process stayed alive (kill -0succeeded, RSS constant),ss -tnshowed the wedged connection with a constant ~1.8 MB in Send-Q, and the daemon thread sat inwait_woken(from/proc/<pid>/task/*/wchan). The same wedge was re-confirmed on 0.3.11.post1. Expected secure behavior: the daemon enforces a write timeout, drops the connection, and keeps serving other peers.Impact
This is an uncontrolled-resource-consumption issue (CWE-400) on the engine control plane. The attacker needs no credentials, only reachability to the handshake RPC port, which is picked from the documented 15000-17000 range and published in the
mooncake/rpc_meta/*metadata.While the daemon is wedged, every control-plane operation of that engine fails: new RDMA QP handshakes, P2P segment metadata fetches for peers that have not cached the descriptor, notify delivery, and liveness probes. New transfers that need any of these fail; the engine process itself stays alive, so health checks and orchestrators see a healthy instance while it accepts no new peers - the failure is invisible without trying an actual handshake. Recovery requires restarting the engine process. Availability-only impact; no confidentiality or integrity effect was observed. Suggested CVSS:3.1 vector AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (6.5). Affected: mooncake-transfer-engine <= 0.3.13.post1, no patched version yet.
Before submitting...
@github-actions[bot] commented on GitHub (Oct 1, 2026):
Thanks for opening this issue, @yyymk!
133664083A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide