about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-08-01 12:54:23 -0400
committerRich Felker <dalias@aerifal.cx>2022-08-01 12:54:23 -0400
commit7d568410b455390362e2bcfb7c50fcf9c8833d9b (patch)
tree37c59f182e553256b2c7a84b2bcfc261b934128f /src
parentd16d7b10997e6f1c224c3de01b43868f0ce2cc3d (diff)
downloadmusl-7d568410b455390362e2bcfb7c50fcf9c8833d9b.tar.gz
musl-7d568410b455390362e2bcfb7c50fcf9c8833d9b.tar.xz
musl-7d568410b455390362e2bcfb7c50fcf9c8833d9b.zip
fix mishandling of errno in getaddrinfo AI_ADDRCONFIG logic
this code attempts to use the value of errno from failure of socket or
connect to infer availability of the requested address family (v4 or
v6). however, in the case where connect failed, there is an
intervening call to close between connect and the use of errno. close
is not required to preserve errno on success, and in fact the
__aio_close code, which is called whenever aio is linked and thus
always called in dynamic-linked programs, unconditionally clobbers
errno. as a result, getaddrinfo fails with EAI_SYSTEM and errno=ENOENT
rather than correctly determining that the address family was
unavailable.

this fix is based on report/patch by Jussi Nieminen, but simplified
slightly to avoid breaking the case where socket, not connect, failed.
Diffstat (limited to 'src')
-rw-r--r--src/network/getaddrinfo.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c
index efaab306..9df045f6 100644
--- a/src/network/getaddrinfo.c
+++ b/src/network/getaddrinfo.c
@@ -66,9 +66,11 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
 				pthread_setcancelstate(
 					PTHREAD_CANCEL_DISABLE, &cs);
 				int r = connect(s, ta[i], tl[i]);
+				int saved_errno = errno;
 				pthread_setcancelstate(cs, 0);
 				close(s);
 				if (!r) continue;
+				errno = saved_errno;
 			}
 			switch (errno) {
 			case EADDRNOTAVAIL: