|
Message-ID: <20220824233228.GM7074@brightrain.aerifal.cx> Date: Wed, 24 Aug 2022 19:32:28 -0400 From: Rich Felker <dalias@...c.org> To: Markus Wichmann <nullplan@....net> Cc: musl@...ts.openwall.com Subject: Re: IPv4 fallback in __res_msend_rc not functional On Wed, Aug 24, 2022 at 07:26:58PM -0400, Rich Felker wrote: > On Wed, Aug 24, 2022 at 09:03:49PM +0200, Markus Wichmann wrote: > > Hi all, > > > > I noticed something while reading some code: There is a fallback in > > __res_msend_rc(), in case an IPv6 socket is requested but cannot be > > allocated. In that case, the function tries to create an IPv4 socket > > instead. However, I do not think this code can work that way. For > > reference, this is the code: > > > > /* Get local address and open/bind a socket */ > > sa.sin.sin_family = family; > > fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); > > > > /* Handle case where system lacks IPv6 support */ > > if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) { > > fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); > > family = AF_INET; > > } > > if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) { > > if (fd >= 0) close(fd); > > pthread_setcancelstate(cs, 0); > > return -1; > > } > > > > The problem is, if the fallback is triggered, the local address is still > > set to be an IPv6 address, and so the bind() must necessarily fail with > > EINVAL. > > > > The fix depends on whether the fallback is still intended functionality > > or not. If not, then the easiest would be to just get rid of the entire > > fallback block. If the fallback is still intended to work, then the > > fallback block must reset sl to the length of an IPv4 socket, and the > > setting of sa.sin.sin_family must be delayed until after that block. > > > > There is also the issue of the sendto() loop further down in the > > function. If it is intended that the socket can be an IPv4 socket but > > there can be IPv6 addresses in the list, then it might be prudent to > > prevent sendto() from sending to the wrong address family. Or not, I > > mean, you do not test for errors from sendto(), and the sends to the > > wrong address family are just going to fail. So they would only waste > > time and change errno, but not much of a visible side effect. > > Thanks for reporting this! It's intended to be functional, but it's > probably of little consequence whether it works since the issue seems > to arise only when resolv.conf requested IPv6 nameservers but the > system doesn't support IPv6. I'll look at what it'll take to fix it... > hopefully it won't be too bad. Does this work? diff --git a/src/network/res_msend.c b/src/network/res_msend.c index 3e018009..105bf598 100644 --- a/src/network/res_msend.c +++ b/src/network/res_msend.c @@ -68,14 +68,15 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries, } /* Get local address and open/bind a socket */ - sa.sin.sin_family = family; fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); /* Handle case where system lacks IPv6 support */ if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) { fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); family = AF_INET; + sl = sizeof sa.sin; } + sa.sin.sin_family = family; if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) { if (fd >= 0) close(fd); pthread_setcancelstate(cs, 0);
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.