From 0a513555561d8ee4c1de930996ecc0cf73154378 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 5 Jun 2021 12:57:28 +0200 Subject: [PATCH] Revert "Revert "socketpair: fix potential hangs"" This reverts commit 3e70c3430a370a31eff2c1d8fea29edaca8f1127. Thus brings back the change from #7144 as was originally landed in c769d1eab4de8b Closes #7144 (again) --- lib/socketpair.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/socketpair.c b/lib/socketpair.c index 2c580ad2d..26e1dc66d 100644 --- a/lib/socketpair.c +++ b/lib/socketpair.c @@ -48,6 +48,10 @@ #endif /* !INADDR_LOOPBACK */ #endif /* !WIN32 */ +#include "nonblock.h" /* for curlx_nonblock */ +#include "timeval.h" /* needed before select.h */ +#include "select.h" /* for Curl_poll */ + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -59,12 +63,11 @@ int Curl_socketpair(int domain, int type, int protocol, union { struct sockaddr_in inaddr; struct sockaddr addr; - } a; + } a, a2; curl_socket_t listener; curl_socklen_t addrlen = sizeof(a.inaddr); int reuse = 1; - char data[2][12]; - ssize_t dlen; + struct pollfd pfd[1]; (void)domain; (void)type; (void)protocol; @@ -85,7 +88,8 @@ int Curl_socketpair(int domain, int type, int protocol, goto error; if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) goto error; - if(getsockname(listener, &a.addr, &addrlen) == -1) + if(getsockname(listener, &a.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a.inaddr)) goto error; if(listen(listener, 1) == -1) goto error; @@ -94,18 +98,30 @@ int Curl_socketpair(int domain, int type, int protocol, goto error; if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1) goto error; + + /* use non-blocking accept to make sure we don't block forever */ + if(curlx_nonblock(listener, TRUE) < 0) + goto error; + pfd[0].fd = listener; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + (void)Curl_poll(pfd, 1, 10*1000); /* 10 seconds */ socks[1] = accept(listener, NULL, NULL); if(socks[1] == CURL_SOCKET_BAD) goto error; /* verify that nothing else connected */ - msnprintf(data[0], sizeof(data[0]), "%p", socks); - dlen = strlen(data[0]); - if(swrite(socks[0], data[0], dlen) != dlen) + addrlen = sizeof(a.inaddr); + if(getsockname(socks[0], &a.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a.inaddr)) goto error; - if(sread(socks[1], data[1], sizeof(data[1])) != dlen) + addrlen = sizeof(a2.inaddr); + if(getpeername(socks[1], &a2.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a2.inaddr)) goto error; - if(memcmp(data[0], data[1], dlen)) + if(a.inaddr.sin_family != a2.inaddr.sin_family || + a.inaddr.sin_addr.s_addr != a2.inaddr.sin_addr.s_addr || + a.inaddr.sin_port != a2.inaddr.sin_port) goto error; sclose(listener);