From 07fb67831beffebb9135daf7971cb0cdce65a279 Mon Sep 17 00:00:00 2001 From: Tai An Date: Sun, 2 Aug 2026 12:19:33 -0700 Subject: [PATCH] fix(multinode): use JSON instead of pickle for node-IP exchange to prevent RCE send_and_receive_node_ip() bound a ZMQ PULL socket on tcp://*:PORT (all interfaces) on the head node and read peer data with recv_pyobj(), which calls pickle.loads() on the wire bytes. Any host able to reach the port could send a crafted pickle payload and achieve arbitrary code execution on the head node, the same class of issue as CVE-2025-32444 in vLLM. The only value exchanged is the child node's IP string, which is fully JSON-serializable, so switch the send/recv pair to send_json/recv_json. This removes the pickle deserialization sink without changing behavior. Closes #1413 --- lightllm/utils/multinode_utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lightllm/utils/multinode_utils.py b/lightllm/utils/multinode_utils.py index ffe3c1208c..dcbce7482b 100644 --- a/lightllm/utils/multinode_utils.py +++ b/lightllm/utils/multinode_utils.py @@ -19,7 +19,10 @@ def send_and_receive_node_ip(args): comm_socket = context.socket(zmq.PULL) comm_socket.bind(f"tcp://*:{args.multinode_httpmanager_port + i + 100}") logger.info(f"binding port {args.multinode_httpmanager_port + i + 100}") - args.child_ips.append(comm_socket.recv_pyobj()) + # Use JSON instead of pickle: the payload is only the child IP + # string, and recv_pyobj() -> pickle.loads() on a socket bound to + # all interfaces would allow unauthenticated RCE (cf. CVE-2025-32444). + args.child_ips.append(comm_socket.recv_json()) comm_socket.close() logger.info(f"Received child IPs: {args.child_ips}") else: @@ -28,5 +31,5 @@ def send_and_receive_node_ip(args): comm_socket = context.socket(zmq.PUSH) comm_socket.connect(f"tcp://{args.nccl_host}:{args.multinode_httpmanager_port + args.node_rank + 100}") logger.info(f"connecting to {args.nccl_host}:{args.multinode_httpmanager_port + args.node_rank + 100}") - comm_socket.send_pyobj(local_ip) + comm_socket.send_json(local_ip) comm_socket.close()