parse_ip_val_buffer() validates the parsed token length against out_len,
but several callers passed MAX_IP_ADDR_SIZE * 2 while the destination
buffers are much smaller stack arrays (e.g. INET6_ADDRSTRLEN).

This can lead to out-of-bounds writes via strcpy() when a long token is
parsed from host-provided IP/subnet strings.

Use size_t for out_len, switch to bounded copy with memcpy() + explicit
NUL termination, and pass the actual destination buffer sizes at all
call sites.

Signed-off-by: unknownbbqrx <[email protected]>
---
 tools/hv/hv_kvp_daemon.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index c02f8a341..ecf123bce 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -1188,10 +1188,11 @@ static int is_ipv4(char *addr)
 }
 
 static int parse_ip_val_buffer(char *in_buf, int *offset,
-                               char *out_buf, int out_len)
+                               char *out_buf, size_t out_len)
 {
        char *x;
        char *start;
+       size_t copy_len;
 
        /*
         * in_buf has sequence of characters that are separated by
@@ -1214,8 +1215,10 @@ static int parse_ip_val_buffer(char *in_buf, int *offset,
                while (start[i] == ' ')
                        i++;
 
-               if ((x - start) <= out_len) {
-                       strcpy(out_buf, (start + i));
+               copy_len = x - (start + i);
+               if (copy_len < out_len) {
+                       memcpy(out_buf, start + i, copy_len);
+                       out_buf[copy_len] = '\0';
                        *offset += (x - start) + 1;
                        return 1;
                }
@@ -1249,7 +1252,7 @@ static int process_ip_string(FILE *f, char *ip_string, 
int type)
        memset(addr, 0, sizeof(addr));
 
        while (parse_ip_val_buffer(ip_string, &offset, addr,
-                                       (MAX_IP_ADDR_SIZE * 2))) {
+                                       sizeof(addr))) {
 
                sub_str[0] = 0;
                if (is_ipv4(addr)) {
@@ -1374,7 +1377,7 @@ static int process_dns_gateway_nm(FILE *f, char 
*ip_string, int type,
                memset(addr, 0, sizeof(addr));
 
                if (!parse_ip_val_buffer(ip_string, &ip_offset, addr,
-                                        (MAX_IP_ADDR_SIZE * 2)))
+                                        sizeof(addr)))
                        break;
 
                ip_ver = ip_version_check(addr);
@@ -1426,12 +1429,11 @@ static int process_ip_string_nm(FILE *f, char 
*ip_string, char *subnet,
        memset(subnet_addr, 0, sizeof(subnet_addr));
 
        while (parse_ip_val_buffer(ip_string, &ip_offset, addr,
-                                  (MAX_IP_ADDR_SIZE * 2)) &&
+                                  sizeof(addr)) &&
                                   parse_ip_val_buffer(subnet,
-                                                      &subnet_offset,
-                                                      subnet_addr,
-                                                      (MAX_IP_ADDR_SIZE *
-                                                       2))) {
+                                              &subnet_offset,
+                                              subnet_addr,
+                                              sizeof(subnet_addr))) {
                ip_ver = ip_version_check(addr);
                if (ip_ver < 0)
                        continue;

base-commit: 2e68039281932e6dc37718a1ea7cbb8e2cda42e6
prerequisite-patch-id: b61dd51dee390277603975bf729a687113185c3a
prerequisite-patch-id: df28525061dd528875c7c75880b4684d80f4aa7d
prerequisite-patch-id: 64c48c6f2222781631304d9d4d7d1c712c002610
prerequisite-patch-id: 9be258692732026bf560ed9887adbd02a8887263
-- 
2.53.0




Reply via email to