In AddrsMatch, keep copies of addrinfos to free.

When looping through addrinfo lists matching addresses, keep a copy
of the original addrinfo pointers to free instead of ending up at the
terminating NULLs and trying to free those.

In the best case this fixes a mem leak.  In implementations such as musl
where freeaddrinfo(NULL) is not safe (which is not required by the spec),
this fixes a segfault.
This commit is contained in:
Darren Tucker 2024-02-14 23:28:35 +11:00
parent b7aa0508f0
commit f93b20a3bc

View File

@ -1308,7 +1308,7 @@ AddrsMatch(char *addr1, char *addr2)
{ {
#if USE_IPV6 #if USE_IPV6
int error, ret = 0; int error, ret = 0;
struct addrinfo *ai1, *ai2, hints; struct addrinfo *ai1, *ai2, *rp1, *rp2, hints;
#else #else
/* so, since we might use inet_addr, we're going to use /* so, since we might use inet_addr, we're going to use
* (in_addr_t)(-1) as a sign of an invalid ip address. * (in_addr_t)(-1) as a sign of an invalid ip address.
@ -1346,17 +1346,19 @@ AddrsMatch(char *addr1, char *addr2)
goto done; goto done;
} }
for (; ai1 != NULL; ai1 = ai1->ai_next) { rp1 = ai1;
for (; ai2 != NULL; ai2 = ai2->ai_next) { rp2 = ai2;
if (ai1->ai_addr->sa_family != ai2->ai_addr->sa_family) for (; rp1 != NULL; rp1 = rp1->ai_next) {
for (; rp2 != NULL; rp2 = rp2->ai_next) {
if (rp1->ai_addr->sa_family != rp2->ai_addr->sa_family)
continue; continue;
if ( if (
# if HAVE_MEMCMP # if HAVE_MEMCMP
memcmp(&ai1->ai_addr, &ai2->ai_addr, memcmp(&rp1->ai_addr, &rp2->ai_addr,
sizeof(struct sockaddr_storage)) sizeof(struct sockaddr_storage))
# else # else
bcmp(&ai1->ai_addr, &ai2->ai_addr, bcmp(&rp1->ai_addr, &rp2->ai_addr,
sizeof(struct sockaddr_storage)) sizeof(struct sockaddr_storage))
# endif # endif
== 0) { == 0) {