File: CVE-2025-46836-interface.c-Stack-based-Buffer-Overfl.patch

package info (click to toggle)
net-tools 2.10-0.1%2Bdeb12u2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,876 kB
  • sloc: ansic: 14,668; makefile: 376; sh: 105
file content (92 lines) | stat: -rw-r--r-- 2,921 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
From: Zephkeks <zephyrofficialdiscord@gmail.com>
Date: Tue, 13 May 2025 11:04:17 +0200
Subject: CVE-2025-46836: interface.c: Stack-based Buffer Overflow in
 get_name()
Origin: https://github.com/ecki/net-tools/commit/7a8f42fb20013a1493d8cae1c43436f85e656f2d
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46836
Bug-Debian: https://bugs.debian.org/1105806

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 71d4163ac36f..a054f126e2f1 100644
--- a/lib/interface.c
+++ b/lib/interface.c
@@ -211,32 +211,47 @@ out:
 }
 
 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;
 }
 
-- 
2.49.0