From 46bc5fdc44bf1b840e2b194f492fde5321a4d5d4 Mon Sep 17 00:00:00 2001 From: Jacek Migacz Date: Wed, 23 Apr 2025 13:54:32 +0200 Subject: [PATCH] asyn-thread: issue CURL_POLL_REMOVE before closing socket Resolves: RHEL-85602 --- 0064-curl-7.61.1-EBADF.patch | 140 +++++++++++++++++++++++++++++++++++ curl.spec | 7 +- 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 0064-curl-7.61.1-EBADF.patch diff --git a/0064-curl-7.61.1-EBADF.patch b/0064-curl-7.61.1-EBADF.patch new file mode 100644 index 0000000..edca875 --- /dev/null +++ b/0064-curl-7.61.1-EBADF.patch @@ -0,0 +1,140 @@ +From 17d1e27d309f16da960fd3b9933e6e2b1db22b17 Mon Sep 17 00:00:00 2001 +From: Eric Wong +Date: Sat, 10 Aug 2019 21:20:23 +0000 +Subject: [PATCH] asyn-thread: issue CURL_POLL_REMOVE before closing socket + +This avoids EBADF errors from EPOLL_CTL_DEL operations in the +ephiperfifo.c example. EBADF is dangerous in multi-threaded +applications where I rely on epoll_ctl to operate on the same +epoll description from different threads. + +Follow-up to eb9a604f8d7db8 + +Bug: https://curl.haxx.se/mail/lib-2019-08/0026.html +Closes #4211 +--- + lib/asyn-thread.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index 222e78d98..24da74885 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -164,6 +164,7 @@ struct thread_sync_data { + duplicate */ + int port; + #ifdef HAVE_SOCKETPAIR ++ struct connectdata *conn; + curl_socket_t sock_pair[2]; /* socket pair */ + #endif + int sock_error; +@@ -201,11 +202,10 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd) + Curl_freeaddrinfo(tsd->res); + + #ifdef HAVE_SOCKETPAIR +- /* close socket pair */ +- if(tsd->sock_pair[0] != CURL_SOCKET_BAD) { +- sclose(tsd->sock_pair[0]); +- } +- ++ /* ++ * close one end of the socket pair (may be done in resolver thread); ++ * the other end (for reading) is always closed in the parent thread. ++ */ + if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { + sclose(tsd->sock_pair[1]); + } +@@ -382,6 +382,10 @@ static void destroy_async_data(struct Curl_async *async) + if(async->os_specific) { + struct thread_data *td = (struct thread_data*) async->os_specific; + int done; ++#ifdef HAVE_SOCKETPAIR ++ curl_socket_t sock_rd = td->tsd.sock_pair[0]; ++ struct connectdata *conn = td->tsd.conn; ++#endif + + /* + * if the thread is still blocking in the resolve syscall, detach it and +@@ -403,6 +407,15 @@ static void destroy_async_data(struct Curl_async *async) + + free(async->os_specific); + } ++#ifdef HAVE_SOCKETPAIR ++ /* ++ * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE ++ * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL ++ */ ++ if(conn) ++ Curl_multi_closed(conn->data, sock_rd); ++ sclose(sock_rd); ++#endif + } + async->os_specific = NULL; + +@@ -644,6 +657,8 @@ int Curl_resolver_getsock(struct connectdata *conn, + if(td) { + /* return read fd to client for polling the DNS resolution status */ + socks[0] = td->tsd.sock_pair[0]; ++ DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn); ++ td->tsd.conn = conn; + ret_val = GETSOCK_READSOCK(0); + } + else { +-- +2.49.0 + +From 041690aadb1357775ff06c5bf827a98585627c76 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 30 Jul 2019 10:29:54 +0200 +Subject: [PATCH] asyn-thread: removed unused variable + +Follow-up to eb9a604f. Mistake caused by me when I edited the commit +before push... +--- + lib/asyn-thread.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index f17638e44..e323cbe20 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -636,11 +636,10 @@ int Curl_resolver_getsock(struct connectdata *conn, + struct resdata *reslv = (struct resdata *)data->state.resolver; + #ifdef HAVE_SOCKETPAIR + struct thread_data *td = (struct thread_data*)conn->async.os_specific; +- int loop_idx; + #else + (void)socks; +- (void)numsocks; + #endif ++ (void)numsocks; + + #ifdef HAVE_SOCKETPAIR + if(td) { +-- +2.49.0 + +From 060fb84a5a07388f099c7a3422e281ac64d623a5 Mon Sep 17 00:00:00 2001 +From: Xiang Xiao +Date: Tue, 24 Dec 2019 21:47:37 +0800 +Subject: [PATCH] lib: remove erroneous +x file permission on some c files + +Modified by commit eb9a604 accidentally. + +Closes https://github.com/curl/curl/pull/4756 +--- + lib/asyn-thread.c | 0 + lib/multi.c | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + mode change 100755 => 100644 lib/asyn-thread.c + mode change 100755 => 100644 lib/multi.c + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +old mode 100755 +new mode 100644 +diff --git a/lib/multi.c b/lib/multi.c +old mode 100755 +new mode 100644 +-- +2.49.0 + diff --git a/curl.spec b/curl.spec index d69959e..c112069 100644 --- a/curl.spec +++ b/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.61.1 -Release: 34%{?dist}.3 +Release: 34%{?dist}.4 License: MIT Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz @@ -184,6 +184,9 @@ Patch62: 0062-curl-7.61.1-socketpair-to-wait-on.patch # fix crash, when talking to a NTLM proxy in FIPS mode Patch63: 0063-curl-7.61.1-native-md5.patch +# asyn-thread: issue CURL_POLL_REMOVE before closing socket +Patch64: 0064-curl-7.61.1-EBADF.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -420,6 +423,7 @@ git apply %{PATCH52} %patch -P 61 -p1 %patch -P 62 -p1 %patch -P 63 -p1 +%patch -P 64 -p1 # make tests/*.py use Python 3 sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py @@ -584,6 +588,7 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %changelog * Wed Jan 08 2025 Jacek Migacz - 7.61.1-34.el8_10.4 - make up incomplete patch for host name wildcard checking (RHEL-5680) +- asyn-thread: issue CURL_POLL_REMOVE before closing socket (RHEL-85602) * Wed Oct 30 2024 Jacek Migacz - 7.61.1-34.el8_10.3 - asyn-thread: create a socketpair to wait on (RHEL-34906)