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
This commit is contained in:
Daniel Stenberg 2025-02-07 14:57:36 +01:00
parent c012c6062e
commit c2aa504ab9
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 9 additions and 27 deletions

View File

@ -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) {

View File

@ -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.