[PATCH] tools/hv: fix parse_ip_val_buffer out-of-bounds write
From: unknownbbqrx
Date: Thu Apr 23 2026 - 14:06:48 EST
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 <dev@xxxxxxxxxxxxxxx>
---
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