From 7a8f42fb20013a1493d8cae1c43436f85e656f2d Mon Sep 17 00:00:00 2001
From: Zephkeks <zephyrofficialdiscord@gmail.com>
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;
 }
 
From ddb0e375fb9ca95bb69335540b85bbdaa2714348 Mon Sep 17 00:00:00 2001
From: Bernd Eckenfels <net-tools@lina.inka.de>
Date: Sat, 17 May 2025 21:53:23 +0200
Subject: [PATCH] Interface statistic regression after 7a8f42fb2

---
 lib/interface.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/interface.c b/lib/interface.c
index a054f12..ca4adf1 100644
--- a/lib/interface.c
+++ b/lib/interface.c
@@ -239,12 +239,11 @@ static const char *get_name(char *name, const char *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;
             }
+            if (*p == ':')                  /* consume trailing colon */
+                ++p;
             break;                          /* interface name ends here   */
         }
 
