|
@@ -0,0 +1,93 @@
|
|
|
+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
|
|
|
+
|
|
|
+Upstream: https://github.com/ecki/net-tools/commit/7a8f42fb20013a1493d8cae1c43436f85e656f2d
|
|
|
+Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
|
|
+---
|
|
|
+ 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 @@ 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.39.5
|
|
|
+
|