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

