From bb8e9dabd5534ff89a6d7fdc5cd451ffe4c6254a Mon Sep 17 00:00:00 2001 From: EylonKrause Date: Wed, 24 Jun 2026 15:00:20 +0300 Subject: [PATCH] fix: stack buffer overflow in IPv6 address parsing ncclSocketGetAddrFromString copied operator-controlled [IPv6]:port fields into fixed-size stack buffers (port_str[32], if_name[16]) using strncpy lengths taken directly from the input. A long port or interface field (e.g. NCCL_COMM_ID set to [::1]: followed by 40+ digits) overflowed the stack buffer (CWE-121). Clamp each copy length to its destination buffer size; valid addresses are unaffected. Signed-off-by: EylonKrause --- src/misc/socket.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/misc/socket.cc b/src/misc/socket.cc index f0d9251d53..ed37787f82 100644 --- a/src/misc/socket.cc +++ b/src/misc/socket.cc @@ -296,12 +296,23 @@ ncclResult_t ncclSocketGetAddrFromString(union ncclSocketAddress* ua, const char memset(ip_str, '\0', sizeof(ip_str)); memset(port_str, '\0', sizeof(port_str)); memset(if_name, '\0', sizeof(if_name)); - strncpy(ip_str, ip_port_pair + 1, global_scope ? i - 1 : j - 1); - strncpy(port_str, ip_port_pair + i + 2, len - i - 1); + // Clamp each copy to its destination buffer. These lengths derive from + // operator-controlled input (e.g. NCCL_COMM_ID / NCCL_RAS_ADDR), so an + // over-long IPv6 address, port, or interface name would otherwise overflow + // these fixed stack buffers. The (size_t) cast plus clamp also makes any + // unexpected negative length safe (it becomes large, then clamps down). + size_t ipLen = (size_t)(global_scope ? i - 1 : j - 1); + size_t portLen = (size_t)(len - i - 1); + if (ipLen > sizeof(ip_str) - 1) ipLen = sizeof(ip_str) - 1; + if (portLen > sizeof(port_str) - 1) portLen = sizeof(port_str) - 1; + strncpy(ip_str, ip_port_pair + 1, ipLen); + strncpy(port_str, ip_port_pair + i + 2, portLen); int port = atoi(port_str); if (!global_scope) { // If not global scope, we need the intf name - strncpy(if_name, ip_port_pair + j + 1, i - j - 1); + size_t ifLen = (size_t)(i - j - 1); + if (ifLen > sizeof(if_name) - 1) ifLen = sizeof(if_name) - 1; + strncpy(if_name, ip_port_pair + j + 1, ifLen); } struct sockaddr_in6& sin6 = ua->sin6;