From 7a8f42fb20013a1493d8cae1c43436f85e656f2d Mon Sep 17 00:00:00 2001 From: Zephkeks Date: Tue, 13 May 2025 11:04:17 +0200 Subject: [PATCH] CVE-2025-46836: interface.c: Stack-based Buffer Overflow in get_name() Coordinated as GHSA-pfwf-h6m3-63wf --- lib/interface.c | 63 ++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/lib/interface.c b/lib/interface.c index 71d4163..a054f12 100644 --- a/lib/interface.c +++ b/lib/interface.c @@ -211,32 +211,47 @@ static int if_readconf(void) } static const char *get_name(char *name, const char *p) +/* Safe version — guarantees at most IFNAMSIZ‑1 bytes are copied + and the destination buffer is always NUL‑terminated. */ { - while (isspace(*p)) - p++; - while (*p) { - if (isspace(*p)) - break; - if (*p == ':') { /* could be an alias */ - const char *dot = p++; - while (*p && isdigit(*p)) p++; - if (*p == ':') { - /* Yes it is, backup and copy it. */ - p = dot; - *name++ = *p++; - while (*p && isdigit(*p)) { - *name++ = *p++; - } - } else { - /* No, it isn't */ - p = dot; - } - p++; - break; - } - *name++ = *p++; + char *dst = name; /* current write ptr */ + const char *end = name + IFNAMSIZ - 1; /* last byte we may write */ + + /* Skip leading white‑space. */ + while (isspace((unsigned char)*p)) + ++p; + + /* Copy until white‑space, end of string, or buffer full. */ + while (*p && !isspace((unsigned char)*p) && dst < end) { + if (*p == ':') { /* possible alias veth0:123: */ + const char *dot = p; /* remember the colon */ + ++p; + while (*p && isdigit((unsigned char)*p)) + ++p; + + if (*p == ':') { /* confirmed alias */ + p = dot; /* rewind and copy it all */ + + /* copy the colon */ + if (dst < end) + *dst++ = *p++; + + /* copy the digits */ + while (*p && isdigit((unsigned char)*p) && dst < end) + *dst++ = *p++; + + if (*p == ':') /* consume trailing colon */ + ++p; + } else { /* if so treat as normal */ + p = dot; + } + break; /* interface name ends here */ + } + + *dst++ = *p++; /* ordinary character copy */ } - *name++ = '\0'; + + *dst = '\0'; /* always NUL‑terminate */ return p; }