From: Stefan Eissing Date: Thu, 9 Oct 2025 10:19:49 +0000 (+0200) Subject: cf-socket: set FD_CLOEXEC on all sockets opened X-Git-Tag: rc-8_17_0-1~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9d7b532404181568de1611084bd9f446cd4a4d26;p=thirdparty%2Fcurl.git cf-socket: set FD_CLOEXEC on all sockets opened Removed TODO item Reported-by: Joshua Rogers Closes #18968 --- diff --git a/docs/TODO b/docs/TODO index 65d735d1be..6c3ba904e7 100644 --- a/docs/TODO +++ b/docs/TODO @@ -34,7 +34,6 @@ 1.20 SRV and URI DNS records 1.22 CURLINFO_PAUSE_STATE 1.25 Expose tried IP addresses that failed - 1.28 FD_CLOEXEC 1.30 config file parsing 1.31 erase secrets from heap/stack after use 1.32 add asynch getaddrinfo support @@ -349,14 +348,6 @@ https://github.com/curl/curl/issues/2126 -1.28 FD_CLOEXEC - - It sets the close-on-exec flag for the file descriptor, which causes the file - descriptor to be automatically (and atomically) closed when any of the - exec-family functions succeed. Should probably be set by default? - - https://github.com/curl/curl/issues/2252 - 1.30 config file parsing Consider providing an API, possibly in a separate companion library, for diff --git a/lib/cf-socket.c b/lib/cf-socket.c index 0182de67e8..758641e40d 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -371,6 +371,17 @@ static CURLcode socket_open(struct Curl_easy *data, /* no socket, no connection */ return CURLE_COULDNT_CONNECT; +#ifdef HAVE_FCNTL + if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0) { + char errbuf[STRERROR_LEN]; + failf(data, "fcntl set CLOEXEC: %s", + curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); + close(*sockfd); + *sockfd = CURL_SOCKET_BAD; + return CURLE_COULDNT_CONNECT; + } +#endif + #if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) if(data->conn->scope_id && (addr->family == AF_INET6)) { struct sockaddr_in6 * const sa6 = (void *)&addr->curl_sa_addr; @@ -2122,11 +2133,16 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf, curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); return CURLE_FTP_ACCEPT_FAILED; } - - infof(data, "Connection accepted from server"); -#ifndef HAVE_ACCEPT4 - (void)curlx_nonblock(s_accepted, TRUE); /* enable non-blocking */ +#if !defined(HAVE_ACCEPT4) && defined(HAVE_FCNTL) + if((fcntl(s_accepted, F_SETFD, FD_CLOEXEC) < 0) || + (curlx_nonblock(s_accepted, TRUE) < 0)) { + failf(data, "fcntl set CLOEXEC/NONBLOCK: %s", + curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf))); + return CURLE_FTP_ACCEPT_FAILED; + } #endif + infof(data, "Connection accepted from server"); + /* Replace any filter on SECONDARY with one listening on this socket */ ctx->listening = FALSE; ctx->accepted = TRUE;