From 8a91374487e13cf139ab36e483163a21ebdc6f4e Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Fri, 18 Feb 2022 16:13:12 +0100 Subject: [PATCH] BUG/MINOR: tools: url2sa reads ipv4 too far The url2sa implementation is inconsitent when parsing an IPv4, indeed url2sa() takes a as a parameter where the call to url2ipv4() takes a null terminated string. Which means url2ipv4 could try to read more that it is supposed to. This function is only used from a buffer so it never reach a unallocated space. It can only cause an issue when used from the httpclient which uses it with an ist. This patch fixes the issue by copying everything in the trash and null-terminated it. Must be backported in all supported version. --- src/tools.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/tools.c b/src/tools.c index eca7aa8e2c..c48a9698ca 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1688,12 +1688,20 @@ int url2sa(const char *url, int ulen, struct sockaddr_storage *addr, struct spli return end - url; } else { + /* we need to copy the string into the trash because url2ipv4 + * needs a \0 at the end of the string */ + if (trash.size < ulen) + return -1; + + memcpy(trash.area, curr, ulen - (curr - url)); + trash.area[ulen - (curr - url)] = '\0'; + /* We are looking for IP address. If you want to parse and * resolve hostname found in url, you can use str2sa_range(), but * be warned this can slow down global daemon performances * while handling lagging dns responses. */ - ret = url2ipv4(curr, &((struct sockaddr_in *)addr)->sin_addr); + ret = url2ipv4(trash.area, &((struct sockaddr_in *)addr)->sin_addr); if (ret) { /* Update out. */ if (out) { @@ -1701,7 +1709,9 @@ int url2sa(const char *url, int ulen, struct sockaddr_storage *addr, struct spli out->host_len = ret; } - curr += ret; + /* we need to assign again curr and end from the trash */ + url = trash.area; + curr = trash.area + ret; /* Decode port. */ if (*curr == ':') { -- 2.39.5