|
| 1 | +From c4e1e6b0319f35b0ceafa8b9502fd71798a7bcf7 Mon Sep 17 00:00:00 2001 |
| 2 | + |
| 3 | +Date: Mon, 19 May 2025 11:04:33 -0400 |
| 4 | +Subject: [PATCH] Address CVE-2025-46836 |
| 5 | +Upstream Patch Reference: https://github.com/ecki/net-tools/commit/7a8f42fb20013a1493d8cae1c43436f85e656f2d |
| 6 | + |
| 7 | +--- |
| 8 | + lib/interface.c | 63 ++++++++++++++++++++++++++++++------------------- |
| 9 | + 1 file changed, 39 insertions(+), 24 deletions(-) |
| 10 | + |
| 11 | +diff --git a/lib/interface.c b/lib/interface.c |
| 12 | +index 42cddda..2d6b6a3 100644 |
| 13 | +--- a/lib/interface.c |
| 14 | ++++ b/lib/interface.c |
| 15 | +@@ -211,32 +211,47 @@ out: |
| 16 | + } |
| 17 | + |
| 18 | + static const char *get_name(char *name, const char *p) |
| 19 | ++/* Safe version — guarantees at most IFNAMSIZ‑1 bytes are copied |
| 20 | ++ and the destination buffer is always NUL‑terminated. */ |
| 21 | + { |
| 22 | +- while (isspace(*p)) |
| 23 | +- p++; |
| 24 | +- while (*p) { |
| 25 | +- if (isspace(*p)) |
| 26 | +- break; |
| 27 | +- if (*p == ':') { /* could be an alias */ |
| 28 | +- const char *dot = p++; |
| 29 | +- while (*p && isdigit(*p)) p++; |
| 30 | +- if (*p == ':') { |
| 31 | +- /* Yes it is, backup and copy it. */ |
| 32 | +- p = dot; |
| 33 | +- *name++ = *p++; |
| 34 | +- while (*p && isdigit(*p)) { |
| 35 | +- *name++ = *p++; |
| 36 | +- } |
| 37 | +- } else { |
| 38 | +- /* No, it isn't */ |
| 39 | +- p = dot; |
| 40 | +- } |
| 41 | +- p++; |
| 42 | +- break; |
| 43 | +- } |
| 44 | +- *name++ = *p++; |
| 45 | ++ char *dst = name; /* current write ptr */ |
| 46 | ++ const char *end = name + IFNAMSIZ - 1; /* last byte we may write */ |
| 47 | ++ |
| 48 | ++ /* Skip leading white‑space. */ |
| 49 | ++ while (isspace((unsigned char)*p)) |
| 50 | ++ ++p; |
| 51 | ++ |
| 52 | ++ /* Copy until white‑space, end of string, or buffer full. */ |
| 53 | ++ while (*p && !isspace((unsigned char)*p) && dst < end) { |
| 54 | ++ if (*p == ':') { /* possible alias veth0:123: */ |
| 55 | ++ const char *dot = p; /* remember the colon */ |
| 56 | ++ ++p; |
| 57 | ++ while (*p && isdigit((unsigned char)*p)) |
| 58 | ++ ++p; |
| 59 | ++ |
| 60 | ++ if (*p == ':') { /* confirmed alias */ |
| 61 | ++ p = dot; /* rewind and copy it all */ |
| 62 | ++ |
| 63 | ++ /* copy the colon */ |
| 64 | ++ if (dst < end) |
| 65 | ++ *dst++ = *p++; |
| 66 | ++ |
| 67 | ++ /* copy the digits */ |
| 68 | ++ while (*p && isdigit((unsigned char)*p) && dst < end) |
| 69 | ++ *dst++ = *p++; |
| 70 | ++ |
| 71 | ++ if (*p == ':') /* consume trailing colon */ |
| 72 | ++ ++p; |
| 73 | ++ } else { /* if so treat as normal */ |
| 74 | ++ p = dot; |
| 75 | ++ } |
| 76 | ++ break; /* interface name ends here */ |
| 77 | ++ } |
| 78 | ++ |
| 79 | ++ *dst++ = *p++; /* ordinary character copy */ |
| 80 | + } |
| 81 | +- *name++ = '\0'; |
| 82 | ++ |
| 83 | ++ *dst = '\0'; /* always NUL‑terminate */ |
| 84 | + return p; |
| 85 | + } |
| 86 | + |
| 87 | +-- |
| 88 | +2.34.1 |
| 89 | + |
0 commit comments