Skip to content

[pull] v1.x from libuv:v1.x#190

Open
pull[bot] wants to merge 916 commits into
bazelregistry:v1.xfrom
libuv:v1.x
Open

[pull] v1.x from libuv:v1.x#190
pull[bot] wants to merge 916 commits into
bazelregistry:v1.xfrom
libuv:v1.x

Conversation

@pull

@pull pull Bot commented Apr 28, 2021

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot]

Can you help keep this open source service alive? 💖 Please sponsor : )

bnoordhuis and others added 27 commits December 13, 2024 21:52
Add a version of uv_udp_try_send that can send multiple datagrams.

Uses sendmmsg(2) on platforms that support it (Linux, FreeBSD, macOS),
falls back to a regular sendmsg(2) loop elsewhere.

This work was sponsored by ISC, the Internet Systems Consortium.
Replace comparison of `alloc_cb_called` with the total bytes
read (`bytes_read`) to validate the test's correctness.

Fixes: #4650
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
This patch will update Android API in CI to 29 and will set up the fdsan
in the test runner.

Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Fixes: #4369
Fixes: #4651

Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Refs: #3119

Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Co-authored-by: James M Snell <jasnell@gmail.com>
Changes since version 1.49.2:

* ci: run macOS and iOS tests also on macOS 14 (Saúl Ibarra Corretgé)

* unix,win: map ENOEXEC errno (Saúl Ibarra Corretgé)

* test: skip multicast join test on ENOEXEC (Saúl Ibarra Corretgé)

* ci: make sure the macOS firewall is disabled (Saúl Ibarra Corretgé)

* darwin,test: squelch EBUSY error on multicast join (Saúl Ibarra
  Corretgé)

* build: update minimum cmake to 3.10 (Ben Noordhuis)

* kqueue: use EVFILT_USER for async if available (Jameson Nash)

* unix,win: fix off-by-one in uv_wtf8_to_utf16() (Ben Noordhuis)

* doc: add scala-native-loop to LINKS.md (Julian A Avar C)

* unix: fix build breakage on haiku, openbsd, etc (Jeffrey H. Johnson)

* kqueue: lower overhead in uv__io_check_fd (Andy Pan)

* doc: move cjihrig back to active maintainers (cjihrig)

* build(deps): bump actions/checkout from 3 to 4 (dependabot[bot])

* unix,pipe: fix handling null buffer in uv_pipe_get{sock,peer}name
  (Saúl Ibarra Corretgé)

* unix,win: harmonize buffer checking (Saúl Ibarra Corretgé)

* unix,win: add support for detached threads (Juan José Arboleda)

* src: add uv_thread_set/getname() methods (Santiago Gimeno)

* build: fix qemu builds (Ben Noordhuis)

* win: drop support for windows 8 (Ben Noordhuis)

* linux: fix uv_cpu_info() arm cpu model detection (Ben Noordhuis)

* linux: always use io_uring for epoll batching (Ben Noordhuis)

* doc: clarify repeating timer behavior more (Ben Noordhuis)

* unix,win: handle nbufs=0 in uv_udp_try_send (Ben Noordhuis)

* win: use GetQueuedCompletionStatusEx directly (Saúl Ibarra Corretgé)

* win: enable uv_thread_{get,set}name on MinGW (Saúl Ibarra Corretgé)

* win: drop support for the legacy MinGW (Saúl Ibarra Corretgé)

* win,fs: get (most) fstat when no permission (Jameson Nash)

* win: plug uv_fs_event_start memory leak (amcgoogan)

* test: address FreeBSD kernel bug causing NULL path in fsevents (Juan
  José Arboleda)

* unix: refactor udp sendmsg code (Ben Noordhuis)

* unix,win: add uv_udp_try_send2 (Ben Noordhuis)

* test: fix flaky flaky udp_mmsg test (Juan José Arboleda)

* build: enable fdsan in Android (Juan José Arboleda)

* test: fix udp-multicast-join for FreeBSD (Juan José Arboleda)

* win: fix leak processing fs event (Saúl Ibarra Corretgé)

* src: set a default thread name for workers (Rafael Gonzaga)

* misc: implement uv_getrusage_thread (Juan José Arboleda)
Said symbols are not by default available on Windows Server 2016 but
libuv can still use them when
api-ms-win-core-processthreads-l1-1-3.dll is present.

Fixes: #4677
The CreateProcess API on Windows is still not longPathAware,
even if the process itself is. So, if the cwd used for CreateProcess
is too long, then the call fails with a 'INVALID_DIRECTORY' error.

To deal with this, check the length of the cwd and shorten it if it
is longer than MAX_PATH.
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
On macOS, when calling `spawn`, the child process's stdio buffer
size is 8192 bytes. This is due to the AF_UNIX socket buffer size
being 8192 bytes in the XNU kernel.

When large amounts of data are transferred through the child
process's stdio, this buffer size can cause performance issues.
To mitigate this, the buffer size has been increased to 65536
bytes, aligning it with the behavior on Linux.
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Extend uv_fs_utime, uv_fs_futime and uv_fs_lutime to accept NAN and
INFINITY, with NAN meaning "don't touch the timestamp" and INFINITY
meaning "set to the current timestamp."

Ugly, but it avoids having to add uv_fs_utime2, etc.

UV_FS_UTIME_NOW and UV_FS_UTIME_OMIT constants have been added to make
it more palatable.

Fixes: #4665
Windows provides the `ENABLE_VIRTUAL_TERMINAL_INPUT` flag for TTY input
streams as a companion flag to `ENABLE_VIRTUAL_TERMINAL_PROCESSING`,
which libuv is already setting for TTY output streams.

Setting this flag lets the terminal emulator perform some of the
processing that libuv already currently does for input events,
but most notably enables receiving control sequences that are
otherwise entirely unavailable, e.g. for bracketed paste
(which the Node.js readline implementation added basic support for
in nodejs/node@87af913b66eab78088acfd).

libuv currently already provides translations for key events to
control sequences, i.e. what this mode is intended to provide,
but libuv does not and cannot translate all such events.
Since the control sequences differ from the ones that Windows
has chosen to standardize on, and applications may not be expecting
this change, this is opt-in for now (but ideally will be the default
behavior starting in libuv v2.x, should that ever happen).

Another downside of this change is that not all shells reset
this mode when an application exits. For example, when running a
Node.js program with this flag enabled inside of PowerShell in
Windows terminal, if the application exits while in raw TTY input mode,
neither the shell nor the terminal emulator reset this flag, rendering
the input stream unusable.

While there's general awareness of the problem that console state is
global state rather than per-process (same as on UNIX platforms),
it seems that applications like PowerShell aren't expecting to need to
unset this flag on the input stream, only its output counterpart
(e.g. https://github.com/PowerShell/PowerShell/blob/4e7942135f998ab40fd3ae298b020e161a76d4ef/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs#L1156).

Hence, `uv_tty_reset_mode()` is extended to reset the terminal
to its original state if the new mode is being used.

Refs: nodejs/node@87af913
Refs: microsoft/terminal#4954
StefanStojanovic and others added 30 commits March 30, 2026 22:09
Otherwise calling `RtlGetVersion()` might produce UB. Problem was
causing random crashes in the node.js test suite with stack traces like
this one:
```
node.exe!__report_gsfailure(unsigned __int64 stack_cookie) Line 220
	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\gs\gs_report.c(220)
node.exe!uv__tcp_keepalive(uv_tcp_s * socket, unsigned __int64 on, int idle, unsigned int intvl, unsigned int cnt, unsigned int) Line 109
	at E:\node\deps\uv\src\win\tcp.c(109)
[Inline Frame] node.exe!uv_tcp_keepalive_ex(uv_tcp_s * handle, int on, unsigned int idle, unsigned int intvl, unsigned int cnt) Line 1406
	at E:\node\deps\uv\src\win\tcp.c(1406)
node.exe!uv_tcp_keepalive(uv_tcp_s * handle, int on, unsigned int idle) Line 1395
	at E:\node\deps\uv\src\win\tcp.c(1395)
node.exe!node::TCPWrap::SetKeepAlive(const v8::FunctionCallbackInfo<v8::Value> & args) Line 213
	at E:\node\src\tcp_wrap.cc(213)
[External Code]
node.exe!v8::internal::`anonymous namespace'::Invoke(v8::internal::Isolate * isolate, const v8::internal::`anonymous namespace'::InvokeParams & params) Line 463
	at E:\node\deps\v8\src\execution\execution.cc(463)
node.exe!v8::internal::Execution::Call(v8::internal::Isolate * isolate, v8::internal::DirectHandle<v8::internal::Object> callable, v8::internal::DirectHandle<v8::internal::Object> receiver, v8::base::Vector<const v8::internal::DirectHandle<v8::internal::Object>> args) Line 532
	at E:\node\deps\v8\src\execution\execution.cc(532)
node.exe!v8::Function::Call(v8::Isolate * isolate, v8::Local<v8::Context> context, v8::Local<v8::Value> recv, int argc, v8::Local<v8::Value> * argv) Line 5374
	at E:\node\deps\v8\src\api\api.cc(5374)
node.exe!v8::Function::Call(v8::Local<v8::Context> context, v8::Local<v8::Value> recv, int argc, v8::Local<v8::Value> * argv) Line 5381
	at E:\node\deps\v8\src\api\api.cc(5381)
node.exe!node::InternalMakeCallback(node::Environment * env, v8::Local<v8::Object> resource, v8::Local<v8::Object> recv, const v8::Local<v8::Function> callback, int argc, v8::Local<v8::Value> * argv, node::async_context asyncContext, v8::Local<v8::Value> context_frame) Line 257
	at E:\node\src\api\callback.cc(257)
node.exe!node::AsyncWrap::MakeCallback(const v8::Local<v8::Function> cb, int argc, v8::Local<v8::Value> * argv) Line 695
	at E:\node\src\async_wrap.cc(695)
[Inline Frame] node.exe!node::AsyncWrap::MakeCallback(const v8::Local<v8::Name> symbol, int argc, v8::Local<v8::Value> * argv) Line 101
	at E:\node\src\async_wrap-inl.h(101)
[Inline Frame] node.exe!node::AsyncWrap::MakeCallback(const v8::Local<v8::String> symbol, int argc, v8::Local<v8::Value> * argv) Line 78
	at E:\node\src\async_wrap-inl.h(78)
node.exe!node::ConnectionWrap<node::TCPWrap,uv_tcp_s>::OnConnection(uv_stream_s * handle, int status) Line 73
	at E:\node\src\connection_wrap.cc(73)
node.exe!uv__process_tcp_accept_req(uv_loop_s * loop, uv_tcp_s * handle, uv_req_s * raw_req) Line 1245
	at E:\node\deps\uv\src\win\tcp.c(1245)
node.exe!uv__process_reqs(uv_loop_s * loop) Line 622
	at E:\node\deps\uv\src\win\core.c(622)
node.exe!uv_run(uv_loop_s * loop, <unnamed-tag> mode) Line 736
	at E:\node\deps\uv\src\win\core.c(736)
node.exe!node::SpinEventLoopInternal(node::Environment * env) Line 43
	at E:\node\src\api\embed_helpers.cc(43)
[Inline Frame] node.exe!node::NodeMainInstance::Run(node::ExitCode * exit_code, node::Environment * env) Line 109
	at E:\node\src\node_main_instance.cc(109)
node.exe!node::NodeMainInstance::Run() Line 99
	at E:\node\src\node_main_instance.cc(99)
[Inline Frame] node.exe!node::StartInternal(int argc, char * * argv) Line 1576
	at E:\node\src\node.cc(1576)
node.exe!node::Start(int argc, char * * argv) Line 1583
	at E:\node\src\node.cc(1583)
node.exe!wmain(int argc, wchar_t * * wargv) Line 91
	at E:\node\src\node_main.cc(91)
```

Fixes: #5106
When uv__stream_open() fails inside uv_accept(), the accepted fd is
closed but POLLIN is never re-enabled on the server's IO watcher.
The condition `if (err == 0)` prevents uv__io_start() from being
called on the error path, causing the server to permanently stop
accepting new connections.

Fix by removing the err == 0 guard so POLLIN is re-enabled
unconditionally when no queued fds are present.
Fixes: #5083
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Fixes: #5086
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
futimens() may fail with EPERM on CIFS/SMB shares that do not
support setting timestamps. Since preserving timestamps during
copyfile is best-effort, ignore the return value unconditionally.

Fixes: nodejs/node#56248
Refs: #4396
Fix undeclared identifiers and use fork instead of posix_spawn on AIX/PASE.

Co-authored-by: Korinne Adler <kadler@us.ibm.com>
Co-authored-by: chenyuebiao <chenyuebiao@bytedance.com>
Use STARTUPINFOEXW with PROC_THREAD_ATTRIBUTE_HANDLE_LIST so that only
the stdio handles prepared for each child process are inherited by it.
This closes the race condition where two concurrent uv_spawn calls
could cause handles intended for one child to leak into another child process.

Fixes: #1490
Closes: #3856

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stop `uv__udp_recvmmsg()` from emitting its own callback when
`recvmmsg()` returns `<= 0`, since this duplicates the handing in
`uv__udp_recvmsg()` which emits the same callback again.

Add a regression test that keeps the socket open past
`UV_UDP_MMSG_FREE` and fails on a second terminal callback.

Co-authored-by: Isaac Elbaz <587490+script3r@users.noreply.github.com>
Fixes one of the regressions listed in #2076

Co-authored-by: sturcottelangevin <sturcottelangevin@bhvr.com>
Refactor uv__kqueue_init to use a temporary fd variable and properly
handle errors from uv__cloexec. If setting CLOEXEC fails, close the
kqueue fd and return the error instead of leaking the descriptor.

Fixes: #5081
Replace `UV_HANDLE_READING` flag checks with `stream->read_cb != NULL`
on the Unix side, removing redundant state management.

Refs: #4995
Replace the hard-coded IPv6 address buffer size in `uv_ip6_addr()` with
`INET6_ADDRSTRLEN` to avoid truncation.

`INET6_ADDRSTRLEN` is the standard constant for the maximum length of
an IPv6 address string representation. Using it makes the intent of the
buffer clearer and avoids relying on a magic number.

This is **not** a security fix. The existing code already bounds
`address_part_size` before calling `memcpy()`, so the previous
implementation did not expose a buffer overflow.
Guard `udp_recvmsg_unreachable_error6` in case ipv6 is not supported.

Fixes: #5143
After the fix to limit the max size of uv_fs_sendfile, this code became
incorrect and would busy-loop. It was previously trying to work around
the fact that the return value of uv_fs_sendfile was undefined when the
input argument SSIZE_MAX > INT32_MAX, but that meant it had to ignore
errors. Using the more correct UV__IO_MAX_BYTES value also avoids any UB
with checking the result of uv_fs_sendfile.
With a environment larger than PATH_MAX, AI thinks the loop here could
theoretically write a null byte after `b` when spawning a path of size
NAME_MAX. Re-write this size-check to be a bit less confusing. The
original musl code used a VLA of size `min(PATH_MAX, strlen(p)) + 1`.
Create a manual database for CI to make sure that folks cannot
accidentally change a struct size on a supported platform. Use
`./uv_run_tests sizeof sizeof` to regenerate the list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The fast relaxed read makes this function very difficult and slow to use
correctly, since it means many callers are required to have a fence
instruction instead. Making this always a seq_cst barrier on the pending
field should eliminate an unexpected source of concurrency bugs.
Register the eventfd with EPOLLET to enable edge-triggered notification
where we're able to eliminate the overhead of reading the eventfd via
system call on each wakeup event.

When the eventfd counter reaches the maximum value of the unsigned
64-bit, which may not happen for the entire lifetime of the process, we
rewind the counter and retry.

This optimization saves one system call on each event-loop wakeup,
eliminating the overhead of `read(2)` as well as the extra latency for
each epoll wakeup.

Relands #4400

Co-authored-by: Andy Pan <i@andypan.me>
…5158)

- fix sizeof/ARRAY_SIZE confusion in GetModuleBaseNameW call

   GetModuleBaseNameW expects nSize as a count of WCHARs, but
   sizeof(basename) returns bytes (520), causing the API to believe the
   buffer is twice its actual capacity (260 WCHARs). Use
   ARRAY_SIZE(basename) to pass the correct element count, consistent
   with the _snwprintf_s calls later in the same function. This API
   already had a cap of 255 characters per MAX_NAME on NTFS, so it a
   non-functional change.

 - fix uninitialized variables in uv__kill SIGQUIT path

   Three issues in the SIGQUIT dump-writing path:

     - basename[MAX_PATH] was uninitialized: if GetModuleBaseNameW fails
       (e.g. access denied), the uninitialized buffer would be passed as
       %ls to _snwprintf_s, reading garbage off the stack until a zero
       byte.

     - dump_folder[MAX_PATH] was uninitialized: if both RegGetValueW and
       SHGetKnownFolderPath fail, the garbage value is passed to
       CreateDirectoryW and _snwprintf_s.

     - SHGetKnownFolderPath return value was unchecked: localappdata was
       an indeterminate pointer on failure, causing undefined behavior
       (likely a crash) in the _snwprintf_s call that followed.

   Initialize basename and dump_folder to L"" at declaration, and guard
   _snwprintf_s behind a SUCCEEDED check on SHGetKnownFolderPath.

 - skip dump silently if no valid folder can be determined

   RegGetValueW with ERROR_MORE_DATA leaves the buffer contents
   undefined, so clear dump_folder[0] at the start of the fallback path
   to discard any partial write before attempting SHGetKnownFolderPath.

  Guard all dump-writing code behind dump_folder[0] != L'\0' so that if
  both the registry lookup and SHGetKnownFolderPath fail, we skip
  silently rather than proceeding with an empty path and creating a file
  like \\basename.pid.dmp at the root of the current drive.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
uv_fs_event_start() stores the watched directory path verbatim in
handle->dirw. When an event arrives, the child path is resolved to its
long form with GetLongPathNameW() and uv__relative_path() strips the
handle->dirw prefix off the result.

Previously if the directory was supplied as an 8.3 short path, the
long form no longer shares that prefix, so the prefix check in
uv__relative_path() fails, which either fires an assertion in
builds without NDEBUG or produces a wrong(potentially
out-of-bounds) result otherwise.

This patch falls back to the name reported by ReadDirectoryChangesW
in this case, since that is already relative to the watched directory,
similar to how other branches handle it.

Also update the test to try testing under %TEMP% if accessible to
increase the chance of it reproducing in the CI.
Specifically by returning a NULL addr, otherwise `msg_name` might
contain bogus data. Observed on `FreeBSD` when issuing a `shutdown()` on
a connected udp socket.

Signed-off-by: Santiago Gimeno <santiago.gimeno@gmail.com>
Fixes: #5161
All CI workflows lacked a top-level permissions block, leaving each run
to inherit the repository default (potentially write-all). Each workflow
now has `permissions: read-all` at the top level.

Every action reference that used a mutable version tag was pinned to its
full commit SHA, preventing silent tag-rewriting supply-chain attacks.

Verified with zizmor --min-severity high: no findings after this patch.

Signed-off-by: Alb3e3 <tomaska.filip@gmail.com>
Specifically on AIX and SunOS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.