Skip to content

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

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

pull[bot] wants to merge 1020 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 August 23, 2025 20:41
Rationale for changing it to an enum:

- frees up some bits that can be used for other things
- is potentially faster (direct vs. indirect call)
- is potentially more secure (makes UAF or overruns harder to exploit,
  no arbitrary function pointer to clobber)

Fixes: #4842
The static initial table reserved space for MxN elements but only used
every Nth element. Removing the excess elements shrinks the table 16x.

I added search/insertion/deletion time logging while here to ensure no
performance regressions.

Fixes: #4823
Fix build breakage introduced a couple of days ago in commit 3813460
("unix: replace uv__io_t callback pointer with enum"). Mea culpa.

Fixes: #4864
uv__signal_event() is invoked directly from uv__io_poll(), so the
UV__SIGNAL_EVENT case in uv__io_cb() is never reached.

Refs: #4854 (comment)
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Without -Werror=unknown-warning-option, these conditional argument
additions would not work as intended on clang.
_snwprintf_s takes its length argument in characters, not bytes.

Does not appear to be a security issue because the paths are not under
an attacker's control unless the system has been compromised beyond
salvation: requires a combination of being able to set the name of the
executable and/or changing %LOCALAPPDATA% or a registry key.

Refs: https://github.com/libuv/libuv/security/advisories/GHSA-jjrx-vr7q-7732
There is a minor error about the return value of uv_cancel
for tasks that are already executing. All other parts of the
documentation correctly states that uv_cancel will fail.
Use libuv's OS-independent implementation to look up UV_THREADPOOL_SIZE.

Fixes: #4887
While unlikely that this fails (since it is implemented to call
`abort()` instead of actually return an error code, we would
theoretically leak this state. The process state init doesn't actually
have a cleanup, and just awkwardly relies on uv_signal_close being
unnecessary (which is likely true though).
#4901)

The test previously assumed a default nice value of 0, but this can vary
depending on PAM configuration, /etc/security/limits.conf, or other environment
settings.

Fixes: #4898

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

Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Add a stub function for no-ahafs builds. src/unix/core.c won't actually
call uv__ahafs_event but the linker still needs to see a symbol.
Fixes: #4447
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
Co-authored-by: theanarkh <theratliter@gmail.com>
Add a stub function for no-ahafs builds. src/unix/core.c won't actually
call uv__ahafs_event but the linker still needs to see a symbol.

Like commit 87943b0 but for IBM i instead of AIX this time.
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
The `flags` argument to `uv__udp_recvmsg_errqueue` was not initialized
in all code paths. Shuffle code around to make the control flow more
obvious (at the cost of a less legible diff.)

Also fixes an unused label warning when building on systems that aren't
Linux.

Introduced last month in commit 80a5e3b, "linux: add MSG_ERRQUEUE
ipv4/ipv6 udp support".
When `wtf8_ptr` is NULL, the length will be stored in `wtf8_len_ptr` (not in `wtf8_ptr`).

Fixes: #4934
---------

Signed-off-by: Andy Pan <i@andypan.me>
PickBas and others added 30 commits September 30, 2026 10:16
Refs: nodejs/node#61397

Signed-off-by: PickBas <sayed.kirill@gmail.com>
The Darwin select fallback keeps the original stream descriptor in
`s->fd` while the I/O watcher uses a socketpair. Stream cleanup joins
the selector thread and closes the socketpair, but did not close that
original descriptor.
uv_fs_event_start() opens the path with FILE_LIST_DIRECTORY to tell
files and directories apart. On a file that is FILE_READ_DATA, so the
open takes part in the sharing check and fails with
ERROR_SHARING_VIOLATION when some other process has the file open
without FILE_SHARE_READ: a compiler emitting an object file, an
installer, a virus scanner. Up to 1.51.0 the type was determined with
GetFileAttributesW(), which never opened the path, so watching such a
file used to work.

Probe the type with FILE_READ_ATTRIBUTES instead. It is all that
GetFileInformationByHandle() needs and it stays out of the sharing
check. Then open what is actually watched, the path itself when it is a
directory and its parent otherwise, and check the type of that handle
too.

Metadata still never comes from a path lookup, so the race fixed in
#4948 stays fixed, and the directory case gains the same post-open check
the file case already had.

The file branch still opens the parent by name and keeps its post-open
directory check; Win32 has no relative open short of NtCreateFile.

Fixes: #5270
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This reverts commit cc6d059
due to failing CI (mea culpa).
glibc's fork-based posix_spawn() before the 2.24 (such as CentOS 7,
circa 2012) rewrite has two problems for libuv:

- It never reports exec() failures: posix_spawn() returns 0 and the
  child exits with status 127, so uv_spawn() doesn't return UV_ENOENT or
  UV_EACCES for a missing or non-executable file.

- With POSIX_SPAWN_SETSIGDEF, the child exits with status 127 as soon as
  sigaction() fails for any signal in the set. The sigfillset() set
  libuv passes includes SIGKILL, SIGSTOP and bits past _NSIG, so every
  spawn fails.

Check gnu_get_libc_version() at runtime, as src/unix/thread.c already
does, and use the fork() path on glibc < 2.24.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
EFTYPE was never defined on Linux until 7.2. Now that newer kernel
headers define it but older kernel headers don't, we get different
values for UV_EFTYPE depending on where libuv is compiled: -4028 vs.
-134, -136, -169 or -258; the exact value depends on the architecture.

This commit technically breaks ABI because people that compile libuv
against kernel headers will see the value of UV_EFTYPE flip, but since
older kernels don't return the value, and downstream users therefore
are unlikely to actually see or use it, it's probably fine.

The alternative is to remap the new EFTYPE value to the old one
everywhere but that's both a lot of work and it adds overhead.

Fixes: #5327
Bumps [vmactions/solaris-vm](https://github.com/vmactions/solaris-vm) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/vmactions/solaris-vm/releases)
- [Commits](vmactions/solaris-vm@a11f407...87d3c43)

---
updated-dependencies:
- dependency-name: vmactions/solaris-vm
  dependency-version: 1.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vmactions/openbsd-vm](https://github.com/vmactions/openbsd-vm) from 1.4.7 to 1.4.8.
- [Release notes](https://github.com/vmactions/openbsd-vm/releases)
- [Commits](vmactions/openbsd-vm@86cdc08...5f7b2c9)

---
updated-dependencies:
- dependency-name: vmactions/openbsd-vm
  dependency-version: 1.4.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vmactions/netbsd-vm](https://github.com/vmactions/netbsd-vm) from 1.5.0 to 1.5.2.
- [Release notes](https://github.com/vmactions/netbsd-vm/releases)
- [Commits](vmactions/netbsd-vm@20ee93a...c8a0d7d)

---
updated-dependencies:
- dependency-name: vmactions/netbsd-vm
  dependency-version: 1.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
On i386 the SysV ABI only aligns int64_t to 4 bytes inside structs, so
uv_timespec64_t and uv_timeval64_t are 12 bytes, not 16 as on arm.

test-platform-output parsed the uint64_t cgroup quota and period with
"%lu", which on 32-bit targets only writes the low half and leaves the
rest uninitialized. Use SCNu64 instead.

Fixes: #5303

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This reverts commit 7a02ab5, with fixes so that
ReOpenFile works as documented by calling the internal NtCreateFile operation
directly instead.

ReOpenFile() cannot reopen a directory handle: it unconditionally asks the
kernel for a non-directory file, so the underlying NtCreateFile() call fails
with STATUS_FILE_IS_A_DIRECTORY, which Windows' NTSTATUS-to- Win32 mapping
reports as the misleading ERROR_ACCESS_DENIED. This broke every directory watch
(uv_fs_event_start() on a directory), which is why CI failed across all Windows
configurations and the fix for #5272 had to be reverted.

Add uv__reopen_file(), a small wrapper around NtCreateFile() that reopens a
handle relative to itself (RootDirectory set to the handle, name left empty).
This achieves the same thing ReOpenFile() does for files, but also works for
directories, and keeps the original fix's goal of never resolving the path a
second time (so a concurrent rename cannot swap the watched directory out from
under us).

Verified on native Windows (cross-compiled with mingw, run via WSL2 interop)
that the previous revision reproduces the exact CI failure (`error: -4048`,
UV_EPERM from ReOpenFile()'s ERROR_ACCESS_DENIED) on every directory-watching
fs_event test, and that this fix resolves all of them with no regressions
elsewhere in the suite.

I've asked Microsoft to fix `ReOpenFile`, but that would take a long time, if
they ever do: MicrosoftDocs/sdk-api#2262

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Available on DragonFlyBSD since 4.3 from 2016, and on OpenBSD since 5.7
from 2015, so at this point it should be safe to assume the system call
is present.
The continuation-byte check combines high bits with XOR, allowing
invalid bytes to cancel each other out. E2 41 42 is decoded as U+2042
and successfully converted to IDNA instead of being rejected.

Validate each continuation byte before decoding the code point while
preserving valid-input behavior and cursor advancement on errors.

Add decoder, IDNA and synchronous/asynchronous getaddrinfo regressions.
Co-authored-by: gengjiawen <technicalcute@gmail.com>
Cygwin implements posix_spawn as fork plus a semaphore wait. The child
then overlays a native image, and exits 127 if that exec fails. libuv
already blocks signals across its own fork so a handler cannot run
there. On Cygwin, block SIGCHLD around posix_spawn so its handler cannot
run inside that call.

The mask is restored before the process handle is queued. posix_spawn
still installs an empty mask in the child.

Fixes: #5335
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@3e5f45b...9000827)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@043fb46...cf430e0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) from 1.5.8 to 1.5.9.
- [Release notes](https://github.com/vmactions/freebsd-vm/releases)
- [Commits](vmactions/freebsd-vm@a2f9a41...c46abac)

---
updated-dependencies:
- dependency-name: vmactions/freebsd-vm
  dependency-version: 1.5.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
A recursive uv_fs_event_t reports changes for a whole tree through one
ReadDirectoryChangesW buffer, which libuv has always set at 4 KB. The system
discards everything in it when it overflows, and the callback gets a NULL
filename.

This is easy to hit. libuv only issues the next read once the callbacks for the
previous batch have returned, so the loop is often busy with the consumer's
response to earlier changes, and about 13 file writes arriving in that window
are enough to overflow it. Installing a package into node_modules overflows
more often than not.

Give recursive handles 64 KB instead. Each change is a 12-byte record plus its
relative path in UTF-16, so creating and writing a file with a 50-character
path costs about 310 bytes, and 64 KB holds about 210 such files. 64 KB is also
the largest size that works on network shares: larger sizes are accepted by the
call, but the read then fails with ERROR_INVALID_PARAMETER.

Non-recursive watches keep 4 KB. The system matches each handle's buffer with
its own buffer of the same size, and programs that watch directories one at a
time can hold thousands of handles. Flat watches also have shorter relative
paths, and an overflow there costs a single directory listing to recover from.

The system keeps the buffer size and the recursive setting from the first call
on a handle, so every call has to pass the same size. Store the recursive bit
in a new flag. This also fixes the re-arm, which tested UV_FS_EVENT_RECURSIVE
against the handle flags, where that bit is UV_HANDLE_ACTIVE, and so always
asked for a recursive watch. That was harmless because the system ignores the
change.

Refs: #626
Refs: nodejs/node#58506
The one-time probe for working CLONE_VM (broken under QEMU and WSL1)
used vfork(), whose child raises SIGCHLD on exit. That signal reached
user SIGCHLD watchers during the first uv_spawn(). SIGCHLD is only
advisory (it also fires for stops, other code's children, and exits
can merge), so this is not a contract violation, but it is avoidable.

On Linux, probe with clone(CLONE_VM|CLONE_VFORK) and no exit signal,
reaped with waitpid(__WCLONE). Resetting the handler around vfork()
would not hide it from signalfd()/sigwaitinfo(), which keep blocked
signals pending, and a clone child is also invisible to waitpid(-1).

Block all signals around the probe, as glibc's posix_spawn() does:
the child shares our memory and TLS, so a handler running in it could
corrupt the parent or overflow the small clone() stack. AIX and PASE
keep vfork(), now with signals blocked as well.

Fixes: #5313
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
uv_get_constrained_memory() reads memory.soft_limit_in_bytes on cgroup
v1 and returns min(soft, hard). The v1 soft limit is not a constraint:
the kernel only uses it as a reclaim target when the host is under
memory pressure and never throttles or OOM-kills the cgroup for
exceeding it. It is deprecated as of Linux 6.12. This differs from
cgroup v2's memory.high, which is enforced, so the analogy that put
the soft limit in the "high" slot does not hold.

Docker --memory-reservation and ECS memoryReservation write this file,
so Node.js containers with a small reservation and no hard limit got a
V8 heap clamped to 256 MB on an 8 GB AWS Fargate task.

Only consider memory.limit_in_bytes on cgroup v1.

Fixes: #5359
Refs: #3754
Refs: nodejs/node#47259
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: NUAAwqy <146524024+NUAAwqy@users.noreply.github.com>
All our supported platforms support O_CLOEXEC nowadays. Remove the
fallback code, it's dead code now.

Dishonorable mention to macOS for still not supporting pipe2() and
dup3() in this day and age.

Fixes: #5347
GHA is about to remove them so drop them from the CI matrix.
These are arguably runtime errors and should be reported to the connect
callback, not returned as error codes.

Fixes: #5358
It was reported that AIX and IBM i lack these system calls.
z/OS doesn't seem to have them either so let's be proactive.

Refs: #5357 (comment)
uv_spawn() removed the handle from loop->handle_queue on error and
uv_close() removed it again. uv__queue_remove() doesn't reset the
handle's links, so the second call clobbers whatever they point to.

uv_close() must be called after a failed uv_spawn() anyway, so leave
the handle in the queue and let uv_close() remove it.

Refs: #4980
Not doing so is bug prone: calling uv__queue_remove twice on the same
queue corrupts whatever it's pointing at.

Refs: #5352
Allow applications to skip LaunchServices registration and display name
updates by setting UV_PROCESS_TITLE_USE_LAUNCH_SERVICES=0 at startup
Keep the default enabled to preserve Activity Monitor behavior.

Capture the setting in uv_setup_args so concurrent title updates do not
read the environment, and retain argv updates and thread naming when
LaunchServices is disabled.

Add regression coverage for value parsing, repeated updates and setting
changes after initialization, and document the opt-out.

Fixes: #5300
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.