From: Junio C Hamano Date: Thu, 14 May 2026 21:26:28 GMT Subject: Re: [PATCH 1/3] daemon: fix IPv6 address corruption in lookup_hostname() Message-ID: In-Reply-To: "Sebastien Tardif via GitGitGadget" writes: > From: Sebastien Tardif > > getaddrinfo() is called with AF_UNSPEC hints, so it may return IPv6 > results. However, the code unconditionally casts ai_addr to > sockaddr_in and passes AF_INET to inet_ntop(). On IPv6-only hosts, > this reads from the wrong struct offset, producing garbage IP > addresses. > > Fix this by checking ai_family and extracting the address pointer > into a local variable before calling inet_ntop() once with the > correct family. Die on unexpected address families. > > Signed-off-by: Sebastien Tardif > --- > daemon.c | 15 +++++++++++++-- > 1 file changed, 13 insertions(+), 2 deletions(-) > > diff --git a/daemon.c b/daemon.c > index 0a7b1aae44..80fa0226d8 100644 > --- a/daemon.c > +++ b/daemon.c > @@ -674,9 +674,20 @@ static void lookup_hostname(struct hostinfo *hi) > > gai = getaddrinfo(hi->hostname.buf, NULL, &hints, &ai); > if (!gai) { > - struct sockaddr_in *sin_addr = (void *)ai->ai_addr; > + void *addr; > + > + if (ai->ai_family == AF_INET) { > + struct sockaddr_in *sa = (void *)ai->ai_addr; > + addr = &sa->sin_addr; > + } else if (ai->ai_family == AF_INET6) { > + struct sockaddr_in6 *sa6 = (void *)ai->ai_addr; > + addr = &sa6->sin6_addr; > + } else { > + die("unexpected address family: %d", > + ai->ai_family); > + } The previous iteration used to more explicitly cast ai->ai_addr to the target type, but the use of (void *) here is a cute way to make the result shorter, which makes it a bit easier to read (it may take readers a bit of practice to convince themselves that this type conversion using (void *) as an intermediate type is perfectly fine, though). > > - inet_ntop(AF_INET, &sin_addr->sin_addr, > + inet_ntop(ai->ai_family, addr, > addrbuf, sizeof(addrbuf)); > strbuf_addstr(&hi->ip_address, addrbuf);