From c2aa504ab9148b5c284b090c5043d9f0c3fbd903 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 7 Feb 2025 14:57:36 +0100 Subject: [PATCH] wakeup_write: make sure the eventfd write sends eight bytes The eventfd manpage says: A write(2) fails with the error EINVAL if the size of the supplied buffer is less than 8 bytes When doing x32 on a 64-bit system, pointers are still four bytes so this code must not use the size of a pointer but the size of a 64-bit type. Fixes #16237 Reported-by: Jan Engelhardt Closes #16239 --- lib/asyn-thread.c | 12 ++---------- lib/multi.c | 24 +++++++----------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index 986fc355c1..eb80bc35e9 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -282,14 +282,6 @@ CURL_STDCALL getaddrinfo_thread(void *arg) struct thread_data *td = tsd->td; char service[12]; int rc; -#ifndef CURL_DISABLE_SOCKETPAIR -#ifdef USE_EVENTFD - const void *buf; - const uint64_t val = 1; -#else - char buf[1]; -#endif -#endif msnprintf(service, sizeof(service), "%d", tsd->port); @@ -315,9 +307,9 @@ CURL_STDCALL getaddrinfo_thread(void *arg) #ifndef CURL_DISABLE_SOCKETPAIR if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { #ifdef USE_EVENTFD - buf = &val; + const uint64_t buf[1] = { 1 }; #else - buf[0] = 1; + const char buf[1] = { 1 }; #endif /* DNS has been resolved, signal client task */ if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { diff --git a/lib/multi.c b/lib/multi.c index d4dd4a0047..2b05e94a04 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1538,15 +1538,6 @@ CURLMcode curl_multi_wakeup(CURLM *m) Curl_multi struct that are constant */ struct Curl_multi *multi = m; -#if defined(ENABLE_WAKEUP) && !defined(USE_WINSOCK) -#ifdef USE_EVENTFD - const void *buf; - const uint64_t val = 1; -#else - char buf[1]; -#endif -#endif - /* GOOD_MULTI_HANDLE can be safely called */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -1560,15 +1551,14 @@ CURLMcode curl_multi_wakeup(CURLM *m) making it safe to access from another thread after the init part and before cleanup */ if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) { -#ifdef USE_EVENTFD - buf = &val; - /* eventfd has a stringent rule of requiring the 8-byte buffer when - calling write(2) on it, which makes the sizeof(buf) below fine since - this is only used on 64-bit systems and then the pointer is 64-bit */ -#else - buf[0] = 1; -#endif while(1) { +#ifdef USE_EVENTFD + /* eventfd has a stringent rule of requiring the 8-byte buffer when + calling write(2) on it */ + const uint64_t buf[1] = { 1 }; +#else + const char buf[1] = { 1 }; +#endif /* swrite() is not thread-safe in general, because concurrent calls can have their messages interleaved, but in this case the content of the messages does not matter, which makes it ok to call.