From c50762c3a1e635a6367a2bde6ea6ca746940b163 Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Tue, 23 Jun 2026 13:36:17 -0300 Subject: [PATCH 01/15] Working on v22.23.2 PR-URL: https://github.com/nodejs/node/pull/64067 --- src/node_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_version.h b/src/node_version.h index 98edc11fc4..9253061088 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -24,12 +24,12 @@ #define NODE_MAJOR_VERSION 22 #define NODE_MINOR_VERSION 23 -#define NODE_PATCH_VERSION 1 +#define NODE_PATCH_VERSION 2 #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Jod" -#define NODE_VERSION_IS_RELEASE 1 +#define NODE_VERSION_IS_RELEASE 0 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) From f14d78b9e0201bfe0291f2b0dc4b5d88c70cc28e Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Mon, 8 Jun 2026 13:53:02 +0200 Subject: [PATCH 02/15] http2: retain header memory in session accounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matteo Collina PR-URL: https://github.com/nodejs/node/pull/63752 Reviewed-By: Tim Perry Reviewed-By: Rafael Gonzaga Reviewed-By: Gürgün Dayıoğlu CVE-ID: CVE-2026-56846 --- doc/api/http2.md | 21 +++--- src/node_http2.cc | 13 +++- src/node_http2.h | 4 +- ...ttp2-max-session-memory-stalled-headers.js | 69 +++++++++++++++++++ 4 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 test/parallel/test-http2-max-session-memory-stalled-headers.js diff --git a/doc/api/http2.md b/doc/api/http2.md index 2180d0f70e..539979aa6d 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -2845,9 +2845,10 @@ changes: This is a credit based limit, existing `Http2Stream`s may cause this limit to be exceeded, but new `Http2Stream` instances will be rejected while this limit is exceeded. The current number of `Http2Stream` sessions, - the current memory use of the header compression tables, current data - queued to be sent, and unacknowledged `PING` and `SETTINGS` frames are all - counted towards the current limit. **Default:** `10`. + the current memory use of the header compression tables, header blocks + retained by open streams, current data queued to be sent, and + unacknowledged `PING` and `SETTINGS` frames are all counted towards the + current limit. **Default:** `10`. * `maxHeaderListPairs` {number} Sets the maximum number of header entries. This is similar to [`server.maxHeadersCount`][] or [`request.maxHeadersCount`][] in the `node:http` module. The minimum value @@ -3034,9 +3035,10 @@ changes: credit based limit, existing `Http2Stream`s may cause this limit to be exceeded, but new `Http2Stream` instances will be rejected while this limit is exceeded. The current number of `Http2Stream` sessions, - the current memory use of the header compression tables, current data - queued to be sent, and unacknowledged `PING` and `SETTINGS` frames are all - counted towards the current limit. **Default:** `10`. + the current memory use of the header compression tables, header blocks + retained by open streams, current data queued to be sent, and + unacknowledged `PING` and `SETTINGS` frames are all counted towards the + current limit. **Default:** `10`. * `maxHeaderListPairs` {number} Sets the maximum number of header entries. This is similar to [`server.maxHeadersCount`][] or [`request.maxHeadersCount`][] in the `node:http` module. The minimum value @@ -3196,9 +3198,10 @@ changes: This is a credit based limit, existing `Http2Stream`s may cause this limit to be exceeded, but new `Http2Stream` instances will be rejected while this limit is exceeded. The current number of `Http2Stream` sessions, - the current memory use of the header compression tables, current data - queued to be sent, and unacknowledged `PING` and `SETTINGS` frames are all - counted towards the current limit. **Default:** `10`. + the current memory use of the header compression tables, header blocks + retained by open streams, current data queued to be sent, and + unacknowledged `PING` and `SETTINGS` frames are all counted towards the + current limit. **Default:** `10`. * `maxHeaderListPairs` {number} Sets the maximum number of header entries. This is similar to [`server.maxHeadersCount`][] or [`request.maxHeadersCount`][] in the `node:http` module. The minimum value diff --git a/src/node_http2.cc b/src/node_http2.cc index 403d9982eb..a496e27289 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -907,6 +907,14 @@ BaseObjectPtr Http2Session::RemoveStream(int32_t id) { stream = FindStream(id); if (stream) { streams_.erase(id); + if (stream->current_headers_length_ > 0) { + DecrementCurrentSessionMemory(stream->current_headers_length_); + stream->current_headers_length_ = 0; + } + if (stream->retained_headers_length_ > 0) { + DecrementCurrentSessionMemory(stream->retained_headers_length_); + stream->retained_headers_length_ = 0; + } DecrementCurrentSessionMemory(sizeof(*stream)); } return stream; @@ -1553,7 +1561,10 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) { }); CHECK_EQ(stream->headers_count(), 0); - DecrementCurrentSessionMemory(stream->current_headers_length_); + // Keep the header block charged against maxSessionMemory while the + // corresponding JS objects can still keep it alive for the lifetime of + // the stream. + stream->retained_headers_length_ += stream->current_headers_length_; stream->current_headers_length_ = 0; Local args[] = { diff --git a/src/node_http2.h b/src/node_http2.h index 9104605292..cb0e067aea 100644 --- a/src/node_http2.h +++ b/src/node_http2.h @@ -485,9 +485,11 @@ class Http2Stream : public AsyncWrap, // The Current Headers block... As headers are received for this stream, // they are temporarily stored here until the OnFrameReceived is called - // signalling the end of the HEADERS frame + // signalling the end of the HEADERS frame. nghttp2_headers_category current_headers_category_ = NGHTTP2_HCAT_HEADERS; uint32_t current_headers_length_ = 0; // total number of octets + // Charged against maxSessionMemory while headers stay alive in JS. + uint64_t retained_headers_length_ = 0; std::vector current_headers_; // This keeps track of the amount of data read from the socket while the diff --git a/test/parallel/test-http2-max-session-memory-stalled-headers.js b/test/parallel/test-http2-max-session-memory-stalled-headers.js new file mode 100644 index 0000000000..c04bfd09e6 --- /dev/null +++ b/test/parallel/test-http2-max-session-memory-stalled-headers.js @@ -0,0 +1,69 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const Countdown = require('../common/countdown'); +const assert = require('assert'); +const http2 = require('http2'); + +const { + NGHTTP2_ENHANCE_YOUR_CALM, +} = http2.constants; + +// Regression test: header blocks retained by stalled streams should continue +// to count against maxSessionMemory after they have been handed to JS. +const maxSessionMemory = 1; +const totalRequests = 400; +const cookieCrumbs = 120; + +let accepted = 0; +let rejected = 0; + +const server = http2.createServer({ maxSessionMemory }); +server.on('stream', (stream) => { + accepted++; + stream.on('error', () => {}); + stream.respond(); + stream.write('x'); +}); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`, { + settings: { + initialWindowSize: 0, + }, + }); + client.on('error', () => {}); + + client.on('remoteSettings', common.mustCall(() => { + let destroyed = false; + const countdown = new Countdown(totalRequests, common.mustCall(() => { + assert(rejected > 0); + assert(accepted < totalRequests); + server.close(); + })); + + for (let i = 0; i < totalRequests; i++) { + const headers = [':path', '/']; + for (let j = 0; j < cookieCrumbs; j++) { + headers.push('cookie', 'a=1'); + } + + const req = client.request(headers); + req.on('error', () => {}); + req.on('close', () => { + if (req.rstCode === NGHTTP2_ENHANCE_YOUR_CALM) { + rejected++; + if (!destroyed) { + destroyed = true; + client.destroy(); + } + } + countdown.dec(); + }); + req.end(); + } + })); +})); From 0566c3cccdc99b935646e813f71e2380aedee50d Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Fri, 3 Jul 2026 17:55:14 -0300 Subject: [PATCH 03/15] permission: enforce fs write permission for trace events Signed-off-by: RafaelGSS PR-URL: https://github.com/nodejs-private/node-private/pull/927 CVE-ID: CVE-2026-56847 --- src/node_trace_events.cc | 8 + src/tracing/node_trace_writer.cc | 32 +- src/tracing/node_trace_writer.h | 3 + test/ffi/fixture_library/build/Makefile | 354 +++++++++++ .../fixture_library/build/binding.Makefile | 6 + test/ffi/fixture_library/build/config.gypi | 570 ++++++++++++++++++ .../build/ffi_test_library.target.mk | 155 +++++ test/node_trace.1.log | 1 + .../test-permission-fs-write-trace-events.js | 70 +++ 9 files changed, 1186 insertions(+), 13 deletions(-) create mode 100644 test/ffi/fixture_library/build/Makefile create mode 100644 test/ffi/fixture_library/build/binding.Makefile create mode 100644 test/ffi/fixture_library/build/config.gypi create mode 100644 test/ffi/fixture_library/build/ffi_test_library.target.mk create mode 100644 test/node_trace.1.log create mode 100644 test/parallel/test-permission-fs-write-trace-events.js diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc index 9787b14352..00f4057e08 100644 --- a/src/node_trace_events.cc +++ b/src/node_trace_events.cc @@ -5,7 +5,9 @@ #include "node_external_reference.h" #include "node_internals.h" #include "node_v8_platform-inl.h" +#include "permission/permission.h" #include "tracing/agent.h" +#include "tracing/node_trace_writer.h" #include "util-inl.h" #include @@ -84,6 +86,12 @@ void NodeCategorySet::Enable(const FunctionCallbackInfo& args) { CHECK_NOT_NULL(category_set); const auto& categories = category_set->GetCategories(); if (!category_set->enabled_ && !categories.empty()) { + const std::string filepath = tracing::NodeTraceWriter::GetFilePath( + per_process::cli_options->trace_event_file_pattern, 1); + THROW_IF_INSUFFICIENT_PERMISSIONS( + category_set->env(), + permission::PermissionScope::kFileSystemWrite, + filepath); // Starts the Tracing Agent if it wasn't started already (e.g. through // a command line flag.) StartTracingAgent(); diff --git a/src/tracing/node_trace_writer.cc b/src/tracing/node_trace_writer.cc index 8f053efe93..6940df51d0 100644 --- a/src/tracing/node_trace_writer.cc +++ b/src/tracing/node_trace_writer.cc @@ -8,9 +8,27 @@ namespace node { namespace tracing { +void replace_substring(std::string* target, + const std::string& search, + const std::string& insert) { + size_t pos = target->find(search); + for (; pos != std::string::npos; pos = target->find(search, pos)) { + target->replace(pos, search.size(), insert); + pos += insert.size(); + } +} + NodeTraceWriter::NodeTraceWriter(const std::string& log_file_pattern) : log_file_pattern_(log_file_pattern) {} +std::string NodeTraceWriter::GetFilePath(const std::string& log_file_pattern, + int file_num) { + std::string filepath(log_file_pattern); + replace_substring(&filepath, "${pid}", std::to_string(uv_os_getpid())); + replace_substring(&filepath, "${rotation}", std::to_string(file_num)); + return filepath; +} + void NodeTraceWriter::InitializeOnThread(uv_loop_t* loop) { CHECK_NULL(tracing_loop_); tracing_loop_ = loop; @@ -60,25 +78,13 @@ NodeTraceWriter::~NodeTraceWriter() { } } -void replace_substring(std::string* target, - const std::string& search, - const std::string& insert) { - size_t pos = target->find(search); - for (; pos != std::string::npos; pos = target->find(search, pos)) { - target->replace(pos, search.size(), insert); - pos += insert.size(); - } -} - void NodeTraceWriter::OpenNewFileForStreaming() { ++file_num_; uv_fs_t req; // Evaluate a JS-style template string, it accepts the values ${pid} and // ${rotation} - std::string filepath(log_file_pattern_); - replace_substring(&filepath, "${pid}", std::to_string(uv_os_getpid())); - replace_substring(&filepath, "${rotation}", std::to_string(file_num_)); + std::string filepath(GetFilePath(log_file_pattern_, file_num_)); if (fd_ != -1) { CHECK_EQ(uv_fs_close(nullptr, &req, fd_, nullptr), 0); diff --git a/src/tracing/node_trace_writer.h b/src/tracing/node_trace_writer.h index cd965d77b7..88a802425f 100644 --- a/src/tracing/node_trace_writer.h +++ b/src/tracing/node_trace_writer.h @@ -19,6 +19,9 @@ class NodeTraceWriter : public AsyncTraceWriter { explicit NodeTraceWriter(const std::string& log_file_pattern); ~NodeTraceWriter() override; + static std::string GetFilePath(const std::string& log_file_pattern, + int file_num); + void InitializeOnThread(uv_loop_t* loop) override; void AppendTraceEvent(TraceObject* trace_event) override; void Flush(bool blocking) override; diff --git a/test/ffi/fixture_library/build/Makefile b/test/ffi/fixture_library/build/Makefile new file mode 100644 index 0000000000..203f6a7d12 --- /dev/null +++ b/test/ffi/fixture_library/build/Makefile @@ -0,0 +1,354 @@ +# We borrow heavily from the kernel build setup, though we are simpler since +# we don't have Kconfig tweaking settings on us. + +# The implicit make rules have it looking for RCS files, among other things. +# We instead explicitly write all the rules we care about. +# It's even quicker (saves ~200ms) to pass -r on the command line. +MAKEFLAGS=-r + +# The source directory tree. +srcdir := .. +abs_srcdir := $(abspath $(srcdir)) + +# The name of the builddir. +builddir_name ?= . + +# The V=1 flag on command line makes us verbosely print command lines. +ifdef V + quiet= +else + quiet=quiet_ +endif + +# Specify BUILDTYPE=Release on the command line for a release build. +BUILDTYPE ?= Release + +# Directory all our build output goes into. +# Note that this must be two directories beneath src/ for unit tests to pass, +# as they reach into the src/ directory for data with relative paths. +builddir ?= $(builddir_name)/$(BUILDTYPE) +abs_builddir := $(abspath $(builddir)) +depsdir := $(builddir)/.deps + +# Object output directory. +obj := $(builddir)/obj +abs_obj := $(abspath $(obj)) + +# We build up a list of every single one of the targets so we can slurp in the +# generated dependency rule Makefiles in one pass. +all_deps := + + + +CC.target ?= $(CC) +CFLAGS.target ?= $(CPPFLAGS) $(CFLAGS) +CXX.target ?= $(CXX) +CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS) +LINK.target ?= $(LINK) +LDFLAGS.target ?= $(LDFLAGS) +AR.target ?= $(AR) +PLI.target ?= pli + +# C++ apps need to be linked with g++. +LINK ?= $(CXX.target) + +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need +# to replicate this environment fallback in make as well. +CC.host ?= gcc +CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host) +CXX.host ?= g++ +CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host) +LINK.host ?= $(CXX.host) +LDFLAGS.host ?= $(LDFLAGS_host) +AR.host ?= ar +PLI.host ?= pli + +# Define a dir function that can handle spaces. +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions +# "leading spaces cannot appear in the text of the first argument as written. +# These characters can be put into the argument value by variable substitution." +empty := +space := $(empty) $(empty) + +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces +replace_spaces = $(subst $(space),?,$1) +unreplace_spaces = $(subst ?,$(space),$1) +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) + +# Flags to make gcc output dependency info. Note that you need to be +# careful here to use the flags that ccache and distcc can understand. +# We write to a dep file on the side first and then rename at the end +# so we can't end up with a broken dep file. +depfile = $(depsdir)/$(call replace_spaces,$@).d +DEPFLAGS = -MMD -MF $(depfile).raw + +# We have to fixup the deps output in a few ways. +# (1) the file output should mention the proper .o file. +# ccache or distcc lose the path to the target, so we convert a rule of +# the form: +# foobar.o: DEP1 DEP2 +# into +# path/to/foobar.o: DEP1 DEP2 +# (2) we want missing files not to cause us to fail to build. +# We want to rewrite +# foobar.o: DEP1 DEP2 \ +# DEP3 +# to +# DEP1: +# DEP2: +# DEP3: +# so if the files are missing, they're just considered phony rules. +# We have to do some pretty insane escaping to get those backslashes +# and dollar signs past make, the shell, and sed at the same time. +# Doesn't work with spaces, but that's fine: .d files have spaces in +# their names replaced with other characters. +define fixup_dep +# The depfile may not exist if the input file didn't have any #includes. +touch $(depfile).raw +# Fixup path as in (1). +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef + +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) -o $@ $< $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) -o $@ $< $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c + +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@") + +quiet_cmd_symlink = SYMLINK $@ +cmd_symlink = ln -sf "$<" "$@" + +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) -o $@ $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,--start-group $(LD_INPUTS) $(LIBS) -Wl,--end-group + +# Note: this does not handle spaces in paths +define xargs + $(1) $(word 1,$(2)) +$(if $(word 2,$(2)),$(call xargs,$(1),$(wordlist 2,$(words $(2)),$(2)))) +endef + +define write-to-file + @: >$(1) +$(call xargs,@printf "%s\n" >>$(1),$(2)) +endef + +OBJ_FILE_LIST := ar-file-list + +define create_archive + rm -f $(1) $(1).$(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crs $(1) @$(1).$(OBJ_FILE_LIST) +endef + +define create_thin_archive + rm -f $(1) $(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crsT $(1) @$(1).$(OBJ_FILE_LIST) +endef + +# We support two kinds of shared objects (.so): +# 1) shared_library, which is just bundling together many dependent libraries +# into a link line. +# 2) loadable_module, which is generating a module intended for dlopen(). +# +# They differ only slightly: +# In the former case, we want to package all dependent code into the .so. +# In the latter case, we want to package just the API exposed by the +# outermost module. +# This means shared_library uses --whole-archive, while loadable_module doesn't. +# (Note that --whole-archive is incompatible with the --start-group used in +# normal linking.) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -o $@ -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -o $@ -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) + + +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' + +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain ? instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\ + for p in $(POSTBUILDS); do\ + eval $$p;\ + E=$$?;\ + if [ $$E -ne 0 ]; then\ + break;\ + fi;\ + done;\ + if [ $$E -ne 0 ]; then\ + rm -rf "$@";\ + exit $$E;\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains ? for +# spaces already and dirx strips the ? characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word 1,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "all" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: all +all: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +TOOLSET := target +# Suffix rules, putting all outputs into $(obj). +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD + @$(call do_cmd,cxx,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD + @$(call do_cmd,cc,1) +$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD + @$(call do_cmd,cc,1) + + +ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ + $(findstring $(join ^,$(prefix)),\ + $(join ^,ffi_test_library.target.mk)))),) + include ffi_test_library.target.mk +endif + +quiet_cmd_regen_makefile = ACTION Regenerating $@ +cmd_regen_makefile = cd $(srcdir); /home/rafaelgss/repos/os/node-private/deps/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/home/rafaelgss/repos/os/node-private/out/Release/addons_headers" "-Dnode_gyp_dir=/home/rafaelgss/repos/os/node-private/deps/npm/node_modules/node-gyp" "-Dnode_lib_file=/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/$(Configuration)/node.lib" "-Dmodule_root_dir=/home/rafaelgss/repos/os/node-private/test/ffi/fixture_library" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/home/rafaelgss/repos/os/node-private/test/ffi/fixture_library/build/config.gypi -I/home/rafaelgss/repos/os/node-private/deps/npm/node_modules/node-gyp/addon.gypi -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/include/node/common.gypi "--toplevel-dir=." binding.gyp +Makefile: $(srcdir)/../../../deps/npm/node_modules/node-gyp/addon.gypi $(srcdir)/../../../out/Release/addons_headers/include/node/common.gypi $(srcdir)/binding.gyp $(srcdir)/build/config.gypi + $(call do_cmd,regen_makefile) + +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif diff --git a/test/ffi/fixture_library/build/binding.Makefile b/test/ffi/fixture_library/build/binding.Makefile new file mode 100644 index 0000000000..3fbe2b3dcc --- /dev/null +++ b/test/ffi/fixture_library/build/binding.Makefile @@ -0,0 +1,6 @@ +# This file is generated by gyp; do not edit. + +export builddir_name ?= ./build/. +.PHONY: all +all: + $(MAKE) ffi_test_library diff --git a/test/ffi/fixture_library/build/config.gypi b/test/ffi/fixture_library/build/config.gypi new file mode 100644 index 0000000000..c60a63c3be --- /dev/null +++ b/test/ffi/fixture_library/build/config.gypi @@ -0,0 +1,570 @@ +# Do not edit. File was generated by node-gyp's "configure" step +{ + "variables": { + "use_ccache_win": 0, + "clang": 0, + "llvm_version": "0.0", + "gas_version": "2.42", + "node_enable_experimentals": "false", + "node_prefix": "/usr/local", + "node_install_npm": "true", + "node_install_corepack": "false", + "control_flow_guard": "false", + "node_use_amaro": "true", + "debug_node": "false", + "debug_symbols": "false", + "build_type%": "Release", + "error_on_warn": "false", + "suppress_all_error_on_warn": "false", + "use_prefix_to_find_headers": "false", + "host_arch": "x64", + "target_arch": "x64", + "node_byteorder": "little", + "cargo_rust_target": "", + "want_separate_host_toolset": 0, + "node_use_node_snapshot": "true", + "node_use_node_code_cache": "true", + "node_write_snapshot_as_array_literals": "false", + "node_enable_v8_vtunejit": "false", + "enable_pgo_generate": "false", + "enable_pgo_use": "false", + "enable_lto": "false", + "enable_thin_lto": "false", + "lto_jobs": "", + "single_executable_application": "true", + "node_use_lief": "true", + "node_with_ltcg": "false", + "node_tag": "", + "node_release_urlbase": "", + "node_debug_lib": "false", + "debug_nghttp2": "false", + "node_no_browser_globals": "false", + "node_shared": "false", + "libdir": "lib", + "node_module_version": 147, + "shlib_suffix": "so.147", + "asan": 0, + "ubsan": 0, + "coverage": "false", + "node_target_type": "executable", + "node_library_files": [ + "lib/_http_agent.js", + "lib/_http_client.js", + "lib/_http_common.js", + "lib/_http_incoming.js", + "lib/_http_outgoing.js", + "lib/_http_server.js", + "lib/_tls_common.js", + "lib/_tls_wrap.js", + "lib/assert.js", + "lib/assert/strict.js", + "lib/async_hooks.js", + "lib/buffer.js", + "lib/child_process.js", + "lib/cluster.js", + "lib/console.js", + "lib/constants.js", + "lib/crypto.js", + "lib/dgram.js", + "lib/diagnostics_channel.js", + "lib/dns.js", + "lib/dns/promises.js", + "lib/domain.js", + "lib/dtls.js", + "lib/events.js", + "lib/ffi.js", + "lib/fs.js", + "lib/fs/promises.js", + "lib/http.js", + "lib/http2.js", + "lib/https.js", + "lib/inspector.js", + "lib/inspector/promises.js", + "lib/internal/abort_controller.js", + "lib/internal/assert.js", + "lib/internal/assert/assertion_error.js", + "lib/internal/assert/myers_diff.js", + "lib/internal/assert/utils.js", + "lib/internal/async_context_frame.js", + "lib/internal/async_hooks.js", + "lib/internal/async_local_storage/async_context_frame.js", + "lib/internal/async_local_storage/async_hooks.js", + "lib/internal/async_local_storage/run_scope.js", + "lib/internal/blob.js", + "lib/internal/blocklist.js", + "lib/internal/bootstrap/node.js", + "lib/internal/bootstrap/realm.js", + "lib/internal/bootstrap/shadow_realm.js", + "lib/internal/bootstrap/switches/does_not_own_process_state.js", + "lib/internal/bootstrap/switches/does_own_process_state.js", + "lib/internal/bootstrap/switches/is_main_thread.js", + "lib/internal/bootstrap/switches/is_not_main_thread.js", + "lib/internal/bootstrap/web/exposed-wildcard.js", + "lib/internal/bootstrap/web/exposed-window-or-worker.js", + "lib/internal/buffer.js", + "lib/internal/child_process.js", + "lib/internal/child_process/serialization.js", + "lib/internal/cli_table.js", + "lib/internal/cluster/child.js", + "lib/internal/cluster/primary.js", + "lib/internal/cluster/round_robin_handle.js", + "lib/internal/cluster/shared_handle.js", + "lib/internal/cluster/utils.js", + "lib/internal/cluster/worker.js", + "lib/internal/console/constructor.js", + "lib/internal/console/global.js", + "lib/internal/constants.js", + "lib/internal/crypto/aes.js", + "lib/internal/crypto/argon2.js", + "lib/internal/crypto/certificate.js", + "lib/internal/crypto/cfrg.js", + "lib/internal/crypto/chacha20_poly1305.js", + "lib/internal/crypto/cipher.js", + "lib/internal/crypto/diffiehellman.js", + "lib/internal/crypto/ec.js", + "lib/internal/crypto/hash.js", + "lib/internal/crypto/hashnames.js", + "lib/internal/crypto/hkdf.js", + "lib/internal/crypto/kem.js", + "lib/internal/crypto/keygen.js", + "lib/internal/crypto/keys.js", + "lib/internal/crypto/mac.js", + "lib/internal/crypto/ml_dsa.js", + "lib/internal/crypto/ml_kem.js", + "lib/internal/crypto/pbkdf2.js", + "lib/internal/crypto/random.js", + "lib/internal/crypto/rsa.js", + "lib/internal/crypto/scrypt.js", + "lib/internal/crypto/sig.js", + "lib/internal/crypto/util.js", + "lib/internal/crypto/webcrypto.js", + "lib/internal/crypto/webcrypto_util.js", + "lib/internal/crypto/webidl.js", + "lib/internal/crypto/x509.js", + "lib/internal/data_url.js", + "lib/internal/debugger/inspect.js", + "lib/internal/debugger/inspect_client.js", + "lib/internal/debugger/inspect_helpers.js", + "lib/internal/debugger/inspect_probe.js", + "lib/internal/debugger/inspect_repl.js", + "lib/internal/dgram.js", + "lib/internal/dns/callback_resolver.js", + "lib/internal/dns/promises.js", + "lib/internal/dns/utils.js", + "lib/internal/dtls/dtls.js", + "lib/internal/dtls/state.js", + "lib/internal/dtls/stats.js", + "lib/internal/dtls/symbols.js", + "lib/internal/encoding.js", + "lib/internal/encoding/single-byte.js", + "lib/internal/encoding/util.js", + "lib/internal/error_serdes.js", + "lib/internal/errors.js", + "lib/internal/errors/error_source.js", + "lib/internal/event_target.js", + "lib/internal/events/abort_listener.js", + "lib/internal/events/symbols.js", + "lib/internal/ffi-shared-buffer.js", + "lib/internal/ffi/fast-api.js", + "lib/internal/file.js", + "lib/internal/fixed_queue.js", + "lib/internal/freelist.js", + "lib/internal/freeze_intrinsics.js", + "lib/internal/fs/cp/cp-sync.js", + "lib/internal/fs/cp/cp.js", + "lib/internal/fs/dir.js", + "lib/internal/fs/glob.js", + "lib/internal/fs/promises.js", + "lib/internal/fs/read/context.js", + "lib/internal/fs/recursive_watch.js", + "lib/internal/fs/rimraf.js", + "lib/internal/fs/streams.js", + "lib/internal/fs/sync_write_stream.js", + "lib/internal/fs/utils.js", + "lib/internal/fs/watchers.js", + "lib/internal/heap_utils.js", + "lib/internal/histogram.js", + "lib/internal/http.js", + "lib/internal/http2/compat.js", + "lib/internal/http2/core.js", + "lib/internal/http2/util.js", + "lib/internal/inspector/network.js", + "lib/internal/inspector/network_http.js", + "lib/internal/inspector/network_http2.js", + "lib/internal/inspector/network_resources.js", + "lib/internal/inspector/network_undici.js", + "lib/internal/inspector/webstorage.js", + "lib/internal/inspector_async_hook.js", + "lib/internal/inspector_network_tracking.js", + "lib/internal/js_stream_socket.js", + "lib/internal/legacy/processbinding.js", + "lib/internal/linkedlist.js", + "lib/internal/locks.js", + "lib/internal/main/check_syntax.js", + "lib/internal/main/embedding.js", + "lib/internal/main/eval_stdin.js", + "lib/internal/main/eval_string.js", + "lib/internal/main/inspect.js", + "lib/internal/main/mksnapshot.js", + "lib/internal/main/print_help.js", + "lib/internal/main/prof_process.js", + "lib/internal/main/repl.js", + "lib/internal/main/run_main_module.js", + "lib/internal/main/test_runner.js", + "lib/internal/main/watch_mode.js", + "lib/internal/main/worker_thread.js", + "lib/internal/mime.js", + "lib/internal/modules/cjs/loader.js", + "lib/internal/modules/customization_hooks.js", + "lib/internal/modules/esm/assert.js", + "lib/internal/modules/esm/create_dynamic_module.js", + "lib/internal/modules/esm/get_format.js", + "lib/internal/modules/esm/hooks.js", + "lib/internal/modules/esm/load.js", + "lib/internal/modules/esm/loader.js", + "lib/internal/modules/esm/module_job.js", + "lib/internal/modules/esm/module_map.js", + "lib/internal/modules/esm/resolve.js", + "lib/internal/modules/esm/shared_constants.js", + "lib/internal/modules/esm/translators.js", + "lib/internal/modules/esm/utils.js", + "lib/internal/modules/esm/worker.js", + "lib/internal/modules/helpers.js", + "lib/internal/modules/package_json_reader.js", + "lib/internal/modules/package_map.js", + "lib/internal/modules/run_main.js", + "lib/internal/modules/typescript.js", + "lib/internal/navigator.js", + "lib/internal/net.js", + "lib/internal/options.js", + "lib/internal/per_context/domexception.js", + "lib/internal/per_context/messageport.js", + "lib/internal/per_context/primordials.js", + "lib/internal/perf/event_loop_delay.js", + "lib/internal/perf/event_loop_utilization.js", + "lib/internal/perf/nodetiming.js", + "lib/internal/perf/observe.js", + "lib/internal/perf/performance.js", + "lib/internal/perf/performance_entry.js", + "lib/internal/perf/resource_timing.js", + "lib/internal/perf/timerify.js", + "lib/internal/perf/usertiming.js", + "lib/internal/perf/utils.js", + "lib/internal/priority_queue.js", + "lib/internal/process/execution.js", + "lib/internal/process/finalization.js", + "lib/internal/process/per_thread.js", + "lib/internal/process/permission.js", + "lib/internal/process/pre_execution.js", + "lib/internal/process/promises.js", + "lib/internal/process/report.js", + "lib/internal/process/signal.js", + "lib/internal/process/task_queues.js", + "lib/internal/process/warning.js", + "lib/internal/process/worker_thread_only.js", + "lib/internal/promise_hooks.js", + "lib/internal/querystring.js", + "lib/internal/quic/diagnostics.js", + "lib/internal/quic/quic.js", + "lib/internal/quic/state.js", + "lib/internal/quic/stats.js", + "lib/internal/quic/symbols.js", + "lib/internal/readline/callbacks.js", + "lib/internal/readline/emitKeypressEvents.js", + "lib/internal/readline/interface.js", + "lib/internal/readline/promises.js", + "lib/internal/readline/utils.js", + "lib/internal/repl.js", + "lib/internal/repl/await.js", + "lib/internal/repl/completion.js", + "lib/internal/repl/history.js", + "lib/internal/repl/utils.js", + "lib/internal/socket_list.js", + "lib/internal/socketaddress.js", + "lib/internal/source_map/prepare_stack_trace.js", + "lib/internal/source_map/source_map.js", + "lib/internal/source_map/source_map_cache.js", + "lib/internal/source_map/source_map_cache_map.js", + "lib/internal/stream_base_commons.js", + "lib/internal/streams/add-abort-signal.js", + "lib/internal/streams/compose.js", + "lib/internal/streams/destroy.js", + "lib/internal/streams/duplex.js", + "lib/internal/streams/duplexify.js", + "lib/internal/streams/duplexpair.js", + "lib/internal/streams/end-of-stream.js", + "lib/internal/streams/fast-utf8-stream.js", + "lib/internal/streams/from.js", + "lib/internal/streams/iter/broadcast.js", + "lib/internal/streams/iter/classic.js", + "lib/internal/streams/iter/consumers.js", + "lib/internal/streams/iter/duplex.js", + "lib/internal/streams/iter/from.js", + "lib/internal/streams/iter/pull.js", + "lib/internal/streams/iter/push.js", + "lib/internal/streams/iter/ringbuffer.js", + "lib/internal/streams/iter/share.js", + "lib/internal/streams/iter/transform.js", + "lib/internal/streams/iter/types.js", + "lib/internal/streams/iter/utils.js", + "lib/internal/streams/lazy_transform.js", + "lib/internal/streams/legacy.js", + "lib/internal/streams/operators.js", + "lib/internal/streams/passthrough.js", + "lib/internal/streams/pipeline.js", + "lib/internal/streams/readable.js", + "lib/internal/streams/state.js", + "lib/internal/streams/transform.js", + "lib/internal/streams/utils.js", + "lib/internal/streams/writable.js", + "lib/internal/test/binding.js", + "lib/internal/test/transfer.js", + "lib/internal/test_runner/assert.js", + "lib/internal/test_runner/coverage.js", + "lib/internal/test_runner/harness.js", + "lib/internal/test_runner/mock/loader.js", + "lib/internal/test_runner/mock/mock.js", + "lib/internal/test_runner/mock/mock_timers.js", + "lib/internal/test_runner/reporter/dot.js", + "lib/internal/test_runner/reporter/junit.js", + "lib/internal/test_runner/reporter/lcov.js", + "lib/internal/test_runner/reporter/rerun.js", + "lib/internal/test_runner/reporter/spec.js", + "lib/internal/test_runner/reporter/tap.js", + "lib/internal/test_runner/reporter/utils.js", + "lib/internal/test_runner/reporter/v8-serializer.js", + "lib/internal/test_runner/runner.js", + "lib/internal/test_runner/snapshot.js", + "lib/internal/test_runner/tag_filter.js", + "lib/internal/test_runner/test.js", + "lib/internal/test_runner/tests_stream.js", + "lib/internal/test_runner/utils.js", + "lib/internal/timers.js", + "lib/internal/tls/common.js", + "lib/internal/tls/secure-context.js", + "lib/internal/tls/wrap.js", + "lib/internal/trace_events_async_hooks.js", + "lib/internal/tty.js", + "lib/internal/url.js", + "lib/internal/util.js", + "lib/internal/util/colors.js", + "lib/internal/util/comparisons.js", + "lib/internal/util/debuglog.js", + "lib/internal/util/diff.js", + "lib/internal/util/inspect.js", + "lib/internal/util/inspector.js", + "lib/internal/util/parse_args/parse_args.js", + "lib/internal/util/parse_args/utils.js", + "lib/internal/util/trace_sigint.js", + "lib/internal/util/types.js", + "lib/internal/v8/cpu_profiler.js", + "lib/internal/v8/heap_profile.js", + "lib/internal/v8/startup_snapshot.js", + "lib/internal/v8_prof_polyfill.js", + "lib/internal/validators.js", + "lib/internal/vfs/dir.js", + "lib/internal/vfs/errors.js", + "lib/internal/vfs/fd.js", + "lib/internal/vfs/file_handle.js", + "lib/internal/vfs/file_system.js", + "lib/internal/vfs/provider.js", + "lib/internal/vfs/providers/memory.js", + "lib/internal/vfs/providers/real.js", + "lib/internal/vfs/router.js", + "lib/internal/vfs/setup.js", + "lib/internal/vfs/stats.js", + "lib/internal/vfs/streams.js", + "lib/internal/vfs/watcher.js", + "lib/internal/vm.js", + "lib/internal/vm/module.js", + "lib/internal/wasm_web_api.js", + "lib/internal/watch_mode/files_watcher.js", + "lib/internal/watchdog.js", + "lib/internal/webidl.js", + "lib/internal/webstorage.js", + "lib/internal/webstreams/adapters.js", + "lib/internal/webstreams/compression.js", + "lib/internal/webstreams/encoding.js", + "lib/internal/webstreams/queuingstrategies.js", + "lib/internal/webstreams/readablestream.js", + "lib/internal/webstreams/transfer.js", + "lib/internal/webstreams/transformstream.js", + "lib/internal/webstreams/util.js", + "lib/internal/webstreams/writablestream.js", + "lib/internal/worker.js", + "lib/internal/worker/clone_dom_exception.js", + "lib/internal/worker/io.js", + "lib/internal/worker/js_transferable.js", + "lib/internal/worker/messaging.js", + "lib/module.js", + "lib/net.js", + "lib/os.js", + "lib/path.js", + "lib/path/posix.js", + "lib/path/win32.js", + "lib/perf_hooks.js", + "lib/process.js", + "lib/punycode.js", + "lib/querystring.js", + "lib/quic.js", + "lib/readline.js", + "lib/readline/promises.js", + "lib/repl.js", + "lib/sea.js", + "lib/sqlite.js", + "lib/stream.js", + "lib/stream/consumers.js", + "lib/stream/iter.js", + "lib/stream/promises.js", + "lib/stream/web.js", + "lib/string_decoder.js", + "lib/sys.js", + "lib/test.js", + "lib/test/reporters.js", + "lib/timers.js", + "lib/timers/promises.js", + "lib/tls.js", + "lib/trace_events.js", + "lib/tty.js", + "lib/url.js", + "lib/util.js", + "lib/util/types.js", + "lib/v8.js", + "lib/vfs.js", + "lib/vm.js", + "lib/wasi.js", + "lib/worker_threads.js", + "lib/zlib.js", + "lib/zlib/iter.js" + ], + "node_cctest_sources": [ + "test/cctest/inspector/test_network_requests_buffer.cc", + "test/cctest/inspector/test_node_protocol.cc", + "test/cctest/node_test_fixture.cc", + "test/cctest/test_aliased_buffer.cc", + "test/cctest/test_base64.cc", + "test/cctest/test_base_object_ptr.cc", + "test/cctest/test_cppgc.cc", + "test/cctest/test_crypto_clienthello.cc", + "test/cctest/test_dataqueue.cc", + "test/cctest/test_diagnostics_channel.cc", + "test/cctest/test_environment.cc", + "test/cctest/test_inspector_socket.cc", + "test/cctest/test_inspector_socket_server.cc", + "test/cctest/test_json_utils.cc", + "test/cctest/test_linked_binding.cc", + "test/cctest/test_lru_cache.cc", + "test/cctest/test_node_api.cc", + "test/cctest/test_node_crypto.cc", + "test/cctest/test_node_crypto_env.cc", + "test/cctest/test_node_ipc_serdes.cc", + "test/cctest/test_node_postmortem_metadata.cc", + "test/cctest/test_node_task_runner.cc", + "test/cctest/test_path.cc", + "test/cctest/test_per_process.cc", + "test/cctest/test_platform.cc", + "test/cctest/test_quic_arena.cc", + "test/cctest/test_quic_cid.cc", + "test/cctest/test_quic_error.cc", + "test/cctest/test_quic_preferredaddress.cc", + "test/cctest/test_quic_tokenbucket.cc", + "test/cctest/test_quic_tokens.cc", + "test/cctest/test_report.cc", + "test/cctest/test_sockaddr.cc", + "test/cctest/test_string_bytes.cc", + "test/cctest/test_traced_value.cc", + "test/cctest/test_util.cc", + "test/cctest/node_test_fixture.h" + ], + "napi_build_version": "10", + "node_shared_zlib": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_ada": "false", + "node_shared_simdjson": "false", + "node_shared_simdutf": "false", + "node_shared_brotli": "false", + "node_shared_cares": "false", + "node_shared_gtest": "false", + "node_shared_hdr_histogram": "false", + "node_shared_merve": "false", + "node_shared_nbytes": "false", + "node_shared_nghttp2": "false", + "node_shared_nghttp3": "false", + "node_shared_ngtcp2": "false", + "node_shared_lief": "false", + "node_use_sqlite": "true", + "node_shared_sqlite": "false", + "node_use_ffi": "true", + "node_shared_ffi": "false", + "node_shared_temporal_capi": "false", + "node_shared_uvwasi": "false", + "node_shared_zstd": "false", + "v8_enable_webassembly": 1, + "v8_enable_javascript_promise_hooks": 1, + "v8_enable_lite_mode": 0, + "v8_enable_gdbjit": 1, + "v8_optimized_debug": 1, + "dcheck_always_on": 0, + "v8_enable_object_print": 1, + "v8_random_seed": 0, + "v8_promise_internal_field_count": 1, + "v8_use_siphash": 1, + "v8_enable_maglev": 1, + "v8_enable_pointer_compression": 0, + "v8_enable_sandbox": 0, + "v8_enable_pointer_compression_shared_cage": 0, + "v8_enable_external_code_space": 0, + "v8_enable_31bit_smis_on_64bit_arch": 0, + "v8_enable_extensible_ro_snapshot": 0, + "v8_enable_temporal_support": 0, + "v8_trace_maps": 0, + "node_use_v8_platform": "true", + "node_use_bundled_v8": "true", + "force_dynamic_crt": 0, + "node_enable_d8": "false", + "node_enable_v8windbg": "false", + "v8_enable_hugepage": 0, + "v8_enable_short_builtin_calls": 1, + "v8_enable_wasm_simd256_revec": 1, + "node_use_openssl": "true", + "node_shared_openssl": "false", + "openssl_is_fips": "false", + "node_fipsinstall": "false", + "node_without_node_options": "false", + "openssl_version": 810549375, + "node_use_quic": "false", + "node_use_dtls": "false", + "icu_small": "false", + "icu_system": "false", + "v8_enable_i18n_support": 1, + "icu_gyp_path": "tools/icu/icu-generic.gyp", + "icu_path": "deps/icu-small", + "icu_ver_major": "78", + "icu_endianness": "l", + "icu_data_in": "../../deps/icu-tmp/icudt78l.dat", + "v8_enable_inspector": 1, + "node_section_ordering_info": "", + "node_builtin_shareable_builtins": [ + "deps/undici/undici.js", + "deps/amaro/dist/index.js" + ], + "ossfuzz": "false", + "v8_enable_v8_checks": 0, + "nodedir": "/home/rafaelgss/repos/os/node-private/out/Release/addons_headers", + "python": "/usr/bin/python3.12", + "standalone_static_library": 1 + }, + "target_defaults": { + "include_dirs": [], + "libraries": [], + "defines": [], + "cflags": [], + "conditions": [], + "default_configuration": "Release", + "configurations": { + "Release": {}, + "Debug": {} + } + } +} diff --git a/test/ffi/fixture_library/build/ffi_test_library.target.mk b/test/ffi/fixture_library/build/ffi_test_library.target.mk new file mode 100644 index 0000000000..a24038be38 --- /dev/null +++ b/test/ffi/fixture_library/build/ffi_test_library.target.mk @@ -0,0 +1,155 @@ +# This file is generated by gyp; do not edit. + +TOOLSET := target +TARGET := ffi_test_library +DEFS_Debug := \ + '-DNODE_GYP_MODULE_NAME=ffi_test_library' \ + '-DUSING_UV_SHARED=1' \ + '-DUSING_V8_SHARED=1' \ + '-DV8_DEPRECATION_WARNINGS=1' \ + '-D_GLIBCXX_USE_CXX11_ABI=1' \ + '-D_FILE_OFFSET_BITS=64' \ + '-D_LARGEFILE_SOURCE' \ + '-D__STDC_FORMAT_MACROS' \ + '-DOPENSSL_NO_PINSHARED' \ + '-DOPENSSL_THREADS' \ + '-DDEBUG' \ + '-D_DEBUG' + +# Flags passed to all source files. +CFLAGS_Debug := \ + -fPIC \ + -pthread \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -m64 \ + -g \ + -O0 + +# Flags passed to only C files. +CFLAGS_C_Debug := + +# Flags passed to only C++ files. +CFLAGS_CC_Debug := \ + -fno-rtti \ + -fno-exceptions \ + -fno-strict-aliasing \ + -std=gnu++20 + +INCS_Debug := \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/include/node \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/src \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/openssl/config \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/openssl/openssl/include \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/uv/include \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/zlib \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/v8/include + +DEFS_Release := \ + '-DNODE_GYP_MODULE_NAME=ffi_test_library' \ + '-DUSING_UV_SHARED=1' \ + '-DUSING_V8_SHARED=1' \ + '-DV8_DEPRECATION_WARNINGS=1' \ + '-D_GLIBCXX_USE_CXX11_ABI=1' \ + '-D_FILE_OFFSET_BITS=64' \ + '-D_LARGEFILE_SOURCE' \ + '-D__STDC_FORMAT_MACROS' \ + '-DOPENSSL_NO_PINSHARED' \ + '-DOPENSSL_THREADS' + +# Flags passed to all source files. +CFLAGS_Release := \ + -fPIC \ + -pthread \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -m64 \ + -O3 \ + -fno-omit-frame-pointer + +# Flags passed to only C files. +CFLAGS_C_Release := + +# Flags passed to only C++ files. +CFLAGS_CC_Release := \ + -fno-rtti \ + -fno-exceptions \ + -fno-strict-aliasing \ + -std=gnu++20 + +INCS_Release := \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/include/node \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/src \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/openssl/config \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/openssl/openssl/include \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/uv/include \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/zlib \ + -I/home/rafaelgss/repos/os/node-private/out/Release/addons_headers/deps/v8/include + +OBJS := \ + $(obj).target/$(TARGET)/ffi_test_library.o + +# Add to the list of files we specially track dependencies for. +all_deps += $(OBJS) + +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual. +$(OBJS): TOOLSET := $(TOOLSET) +$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) +$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) + +# Suffix rules, putting all outputs into $(obj). + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# Try building from generated source, too. + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) + +$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD + @$(call do_cmd,cc,1) + +# End of this set of suffix rules +### Rules for final target. +LDFLAGS_Debug := \ + -pthread \ + -rdynamic \ + -m64 + +LDFLAGS_Release := \ + -pthread \ + -rdynamic \ + -m64 + +LIBS := + +$(obj).target/ffi_test_library.so: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) +$(obj).target/ffi_test_library.so: LIBS := $(LIBS) +$(obj).target/ffi_test_library.so: LD_INPUTS := $(OBJS) +$(obj).target/ffi_test_library.so: TOOLSET := $(TOOLSET) +$(obj).target/ffi_test_library.so: $(OBJS) FORCE_DO_CMD + $(call do_cmd,solink) + +all_deps += $(obj).target/ffi_test_library.so +# Add target alias +.PHONY: ffi_test_library +ffi_test_library: $(builddir)/ffi_test_library.so + +# Copy this to the shared library output path. +$(builddir)/ffi_test_library.so: TOOLSET := $(TOOLSET) +$(builddir)/ffi_test_library.so: $(obj).target/ffi_test_library.so FORCE_DO_CMD + $(call do_cmd,copy) + +all_deps += $(builddir)/ffi_test_library.so +# Short alias for building this shared library. +.PHONY: ffi_test_library.so +ffi_test_library.so: $(obj).target/ffi_test_library.so $(builddir)/ffi_test_library.so + +# Add shared library to "all" target. +.PHONY: all +all: $(builddir)/ffi_test_library.so + diff --git a/test/node_trace.1.log b/test/node_trace.1.log new file mode 100644 index 0000000000..5f3be5b0c7 --- /dev/null +++ b/test/node_trace.1.log @@ -0,0 +1 @@ +{"traceEvents":[{"pid":1610388,"tid":1610388,"ts":105658229815,"tts":7219,"ph":"b","cat":"node,node.environment","name":"Environment","dur":0,"tdur":0,"id":"0x62b917612c10","args":{"args":{"args":["out/Release/node","/home/rafaelgss/repos/os/node-private/test/parallel/test-permission-fs-write-trace-events.js"],"exec_args":["--expose-internals","--trace-event-categories=node"]}}},{"pid":1610388,"tid":1610388,"ts":105658229790,"tts":8908,"ph":"I","cat":"node,node.bootstrap","name":"environment","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658223625,"tts":8909,"ph":"I","cat":"node,node.bootstrap","name":"nodeStart","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658224800,"tts":8909,"ph":"I","cat":"node,node.bootstrap","name":"v8Start","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658231956,"tts":9360,"ph":"I","cat":"node,node.bootstrap","name":"bootstrapComplete","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232063,"tts":9467,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232065,"tts":9468,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232068,"tts":9472,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232069,"tts":9472,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232070,"tts":9474,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232071,"tts":9475,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232072,"tts":9476,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232073,"tts":9476,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232074,"tts":9477,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232075,"tts":9478,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232076,"tts":9480,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232077,"tts":9481,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232078,"tts":9482,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232079,"tts":9482,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232080,"tts":9484,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232081,"tts":9485,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232149,"tts":9552,"ph":"b","cat":"node,node.module_timer","name":"require('/home/rafaelgss/repos/os/node-private/test/parallel/test-permission-fs-write-trace-events.js')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658232226,"tts":9630,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232229,"tts":9632,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232229,"tts":9633,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232232,"tts":9635,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232233,"tts":9636,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232234,"tts":9638,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232341,"tts":9744,"ph":"b","cat":"node,node.module_timer","name":"require('../common')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658232466,"tts":9870,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232468,"tts":9871,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232472,"tts":9875,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232473,"tts":9876,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232501,"tts":9905,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232503,"tts":9906,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232503,"tts":9907,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232508,"tts":9912,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232526,"tts":9930,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232527,"tts":9931,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658232956,"tts":10360,"ph":"b","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234040,"tts":11431,"ph":"e","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234046,"tts":11437,"ph":"b","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234067,"tts":11459,"ph":"e","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234070,"tts":11461,"ph":"b","cat":"node,node.module_timer","name":"require('net')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234449,"tts":11841,"ph":"e","cat":"node,node.module_timer","name":"require('net')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234454,"tts":11845,"ph":"b","cat":"node,node.module_timer","name":"require('path')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234465,"tts":11856,"ph":"e","cat":"node,node.module_timer","name":"require('path')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234467,"tts":11858,"ph":"b","cat":"node,node.module_timer","name":"require('util')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234475,"tts":11866,"ph":"e","cat":"node,node.module_timer","name":"require('util')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234477,"tts":11868,"ph":"b","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234770,"tts":12161,"ph":"e","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234773,"tts":12164,"ph":"b","cat":"node,node.module_timer","name":"require('./tmpdir')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658234859,"tts":12250,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234860,"tts":12251,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234890,"tts":12281,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234893,"tts":12285,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234894,"tts":12285,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234896,"tts":12287,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234898,"tts":12289,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234899,"tts":12290,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658234997,"tts":12389,"ph":"b","cat":"node,node.module_timer","name":"require('child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235317,"tts":12708,"ph":"e","cat":"node,node.module_timer","name":"require('child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235321,"tts":12712,"ph":"b","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235329,"tts":12720,"ph":"e","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235330,"tts":12722,"ph":"b","cat":"node,node.module_timer","name":"require('path')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235339,"tts":12730,"ph":"e","cat":"node,node.module_timer","name":"require('path')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235343,"tts":12734,"ph":"b","cat":"node,node.module_timer","name":"require('url')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235353,"tts":12744,"ph":"e","cat":"node,node.module_timer","name":"require('url')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235356,"tts":12747,"ph":"b","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235360,"tts":12751,"ph":"e","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235381,"tts":12772,"ph":"e","cat":"node,node.module_timer","name":"require('./tmpdir')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235384,"tts":12775,"ph":"b","cat":"node,node.module_timer","name":"require('buffer')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235391,"tts":12782,"ph":"e","cat":"node,node.module_timer","name":"require('buffer')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658235443,"tts":12834,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658235448,"tts":12839,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658235448,"tts":12839,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658235542,"tts":12933,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658235548,"tts":12939,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658235550,"tts":12941,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658237967,"tts":15354,"ph":"b","cat":"node,node.module_timer","name":"require('node:worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658237982,"tts":15368,"ph":"e","cat":"node,node.module_timer","name":"require('node:worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238050,"tts":15436,"ph":"e","cat":"node,node.module_timer","name":"require('../common')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238052,"tts":15438,"ph":"b","cat":"node,node.module_timer","name":"require('../common/child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238095,"tts":15481,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238096,"tts":15482,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.lstat","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238134,"tts":15520,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238137,"tts":15523,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238138,"tts":15524,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238140,"tts":15526,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238142,"tts":15528,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238143,"tts":15529,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238250,"tts":15636,"ph":"b","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238258,"tts":15644,"ph":"e","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238260,"tts":15646,"ph":"b","cat":"node,node.module_timer","name":"require('child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238263,"tts":15649,"ph":"e","cat":"node,node.module_timer","name":"require('child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238264,"tts":15650,"ph":"b","cat":"node,node.module_timer","name":"require('./')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238299,"tts":15685,"ph":"e","cat":"node,node.module_timer","name":"require('./')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238300,"tts":15686,"ph":"b","cat":"node,node.module_timer","name":"require('util')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238302,"tts":15688,"ph":"e","cat":"node,node.module_timer","name":"require('util')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238323,"tts":15709,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238326,"tts":15712,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.open","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238327,"tts":15713,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238417,"tts":15803,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.read","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238422,"tts":15808,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238424,"tts":15810,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.close","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238462,"tts":15848,"ph":"e","cat":"node,node.module_timer","name":"require('../common/child_process')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238464,"tts":15850,"ph":"b","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238468,"tts":15854,"ph":"e","cat":"node,node.module_timer","name":"require('worker_threads')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238469,"tts":15855,"ph":"b","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238471,"tts":15857,"ph":"e","cat":"node,node.module_timer","name":"require('assert')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238472,"tts":15858,"ph":"b","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238474,"tts":15860,"ph":"e","cat":"node,node.module_timer","name":"require('fs')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238475,"tts":15861,"ph":"b","cat":"node,node.module_timer","name":"require('../common/tmpdir')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238496,"tts":15882,"ph":"e","cat":"node,node.module_timer","name":"require('../common/tmpdir')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238497,"tts":15883,"ph":"b","cat":"node,node.module_timer","name":"require('trace_events')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238532,"tts":15918,"ph":"e","cat":"node,node.module_timer","name":"require('trace_events')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658238588,"tts":15974,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238617,"tts":16003,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238638,"tts":16024,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238647,"tts":16033,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238648,"tts":16034,"ph":"B","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658238655,"tts":16041,"ph":"E","cat":"node,node.fs,node.fs.sync","name":"fs.sync.mkdir","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658256686,"tts":16845,"ph":"e","cat":"node,node.module_timer","name":"require('/home/rafaelgss/repos/os/node-private/test/parallel/test-permission-fs-write-trace-events.js')","dur":0,"tdur":0,"id":"0x0","args":{}},{"pid":1610388,"tid":1610388,"ts":105658256692,"tts":16851,"ph":"I","cat":"node,node.bootstrap","name":"loopStart","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658256982,"tts":17141,"ph":"X","cat":"node,node.environment","name":"BeforeExit","dur":5,"tdur":5,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658256987,"tts":17147,"ph":"I","cat":"node,node.bootstrap","name":"loopExit","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257177,"tts":17336,"ph":"X","cat":"node,node.environment","name":"RunCleanup","dur":17,"tdur":17,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257179,"tts":17338,"ph":"X","cat":"node,node.environment","name":"RunAndClearNativeImmediates","dur":0,"tdur":1,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257189,"tts":17348,"ph":"X","cat":"node,node.realm","name":"RunCleanup","dur":4,"tdur":4,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257193,"tts":17353,"ph":"X","cat":"node,node.environment","name":"RunAndClearNativeImmediates","dur":0,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257194,"tts":17354,"ph":"X","cat":"node,node.environment","name":"AtExit","dur":1,"tdur":0,"args":{}},{"pid":1610388,"tid":1610388,"ts":105658257202,"tts":17361,"ph":"e","cat":"node,node.environment","name":"Environment","dur":0,"tdur":0,"id":"0x62b917612c10","args":{}},{"pid":1610388,"tid":1610388,"ts":105658224566,"tts":2008,"ph":"M","cat":"__metadata","name":"process_name","dur":0,"tdur":0,"args":{"name":"out/Release/node"}},{"pid":1610388,"tid":1610388,"ts":105658224568,"tts":2010,"ph":"M","cat":"__metadata","name":"version","dur":0,"tdur":0,"args":{"node":"24.18.1-pre"}},{"pid":1610388,"tid":1610388,"ts":105658224568,"tts":2010,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"JavaScriptMainThread"}},{"pid":1610388,"tid":1610388,"ts":105658224575,"tts":2017,"ph":"M","cat":"__metadata","name":"node","dur":0,"tdur":0,"args":{"process":{"versions":{"acorn":"8.16.0","ada":"3.4.4","amaro":"1.1.9","ares":"1.34.6","brotli":"1.2.0","cldr":"48.0","icu":"78.3","llhttp":"9.4.2","merve":"1.2.2","modules":"137","napi":"10","nbytes":"0.1.4","ncrypto":"0.0.1","nghttp2":"1.69.0","nghttp3":"","ngtcp2":"","node":"24.18.1-pre","openssl":"3.5.7","simdjson":"4.6.4","simdutf":"6.4.0","sqlite":"3.53.1","tz":"2026b","undici":"7.28.0","unicode":"17.0","uv":"1.52.1","uvwasi":"0.0.23","v8":"13.6.233.17-node.50","zlib":"1.3.1-e00f703","zstd":"1.5.7"},"arch":"x64","platform":"linux","release":{"name":"node","lts":"Krypton"}}}},{"pid":1610388,"tid":1610400,"ts":105658224596,"tts":13,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"WorkerThreadsTaskRunner::DelayedTaskScheduler"}},{"pid":1610388,"tid":1610401,"ts":105658224646,"tts":15,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610402,"ts":105658224654,"tts":16,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610403,"ts":105658224666,"tts":20,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610404,"ts":105658224670,"tts":8,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610388,"ts":105658224566,"tts":2008,"ph":"M","cat":"__metadata","name":"process_name","dur":0,"tdur":0,"args":{"name":"out/Release/node"}},{"pid":1610388,"tid":1610388,"ts":105658224568,"tts":2010,"ph":"M","cat":"__metadata","name":"version","dur":0,"tdur":0,"args":{"node":"24.18.1-pre"}},{"pid":1610388,"tid":1610388,"ts":105658224568,"tts":2010,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"JavaScriptMainThread"}},{"pid":1610388,"tid":1610388,"ts":105658224575,"tts":2017,"ph":"M","cat":"__metadata","name":"node","dur":0,"tdur":0,"args":{"process":{"versions":{"acorn":"8.16.0","ada":"3.4.4","amaro":"1.1.9","ares":"1.34.6","brotli":"1.2.0","cldr":"48.0","icu":"78.3","llhttp":"9.4.2","merve":"1.2.2","modules":"137","napi":"10","nbytes":"0.1.4","ncrypto":"0.0.1","nghttp2":"1.69.0","nghttp3":"","ngtcp2":"","node":"24.18.1-pre","openssl":"3.5.7","simdjson":"4.6.4","simdutf":"6.4.0","sqlite":"3.53.1","tz":"2026b","undici":"7.28.0","unicode":"17.0","uv":"1.52.1","uvwasi":"0.0.23","v8":"13.6.233.17-node.50","zlib":"1.3.1-e00f703","zstd":"1.5.7"},"arch":"x64","platform":"linux","release":{"name":"node","lts":"Krypton"}}}},{"pid":1610388,"tid":1610400,"ts":105658224596,"tts":13,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"WorkerThreadsTaskRunner::DelayedTaskScheduler"}},{"pid":1610388,"tid":1610401,"ts":105658224646,"tts":15,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610402,"ts":105658224654,"tts":16,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610403,"ts":105658224666,"tts":20,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}},{"pid":1610388,"tid":1610404,"ts":105658224670,"tts":8,"ph":"M","cat":"__metadata","name":"thread_name","dur":0,"tdur":0,"args":{"name":"PlatformWorkerThread"}}]} \ No newline at end of file diff --git a/test/parallel/test-permission-fs-write-trace-events.js b/test/parallel/test-permission-fs-write-trace-events.js new file mode 100644 index 0000000000..66204d498b --- /dev/null +++ b/test/parallel/test-permission-fs-write-trace-events.js @@ -0,0 +1,70 @@ +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +const { spawnSyncAndExitWithoutError } = require('../common/child_process'); +const { isMainThread } = require('worker_threads'); + +if (!isMainThread) { + common.skip('This test only works on a main thread'); +} + +const assert = require('assert'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +try { + require('trace_events'); +} catch { + common.skip('missing trace events'); +} + +if (!process.permission) { + tmpdir.refresh(); + + const allowed = tmpdir.resolve('allowed'); + const outside = tmpdir.resolve('outside'); + const traceFilePattern = tmpdir.resolve( + 'outside', + // eslint-disable-next-line no-template-curly-in-string + 'denied-node-trace.${rotation}.log'); + const traceFile = tmpdir.resolve('outside', 'denied-node-trace.1.log'); + fs.mkdirSync(allowed); + fs.mkdirSync(outside); + + spawnSyncAndExitWithoutError(process.execPath, [ + '--permission', + '--allow-fs-read=*', + `--allow-fs-write=${allowed}`, + '--trace-event-file-pattern', + traceFilePattern, + __filename, + 'child', + traceFile, + ], { cwd: outside }); + return; +} + +assert.strictEqual(process.argv[2], 'child'); +const traceFile = process.argv[3]; + +assert.throws(() => { + fs.writeFileSync('canary', 'x'); +}, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', +})); + +const tracing = require('trace_events').createTracing({ + categories: ['node', 'v8', 'node.perf'], +}); + +assert.throws(() => { + tracing.enable(); +}, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: traceFile, +})); + +assert.strictEqual(fs.existsSync(traceFile), false); From daa6d25e3dceb30edb832a778ec0610c8bc2dd12 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Wed, 1 Jul 2026 09:43:01 +0200 Subject: [PATCH 04/15] http2: defer rst stream while in scope Signed-off-by: Matteo Collina PR-URL: https://github.com/nodejs-private/node-private/pull/921 Refs: https://hackerone.com/reports/3833629 Reviewed-By: Rafael Gonzaga CVE-ID: CVE-2026-56848 --- src/node_http2.cc | 12 +++- .../test-http2-rst-stream-reentrancy.js | 68 +++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-http2-rst-stream-reentrancy.js diff --git a/src/node_http2.cc b/src/node_http2.cc index a496e27289..38ba01587a 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -2534,10 +2534,18 @@ void Http2Stream::SubmitRstStream(const uint32_t code) { // if RST_STREAM received is not in scope and added to the list // causing endpoint to hang. if (session_->is_in_scope() && is_stream_cancel(code)) { - session_->AddPendingRstStream(id_); - return; + session_->AddPendingRstStream(id_); + return; } + // If RST_STREAM is submitted while nghttp2 is processing callbacks for + // a refused stream, don't force purge pending data. Sending pending data + // here can re-enter nghttp2 and close streams that are still being used + // by the active receive operation. + if (session_->is_in_scope() && code == NGHTTP2_REFUSED_STREAM) { + FlushRstStream(); + return; + } // If possible, force a purge of any currently pending data here to make sure // it is sent before closing the stream. If it returns non-zero then we need diff --git a/test/parallel/test-http2-rst-stream-reentrancy.js b/test/parallel/test-http2-rst-stream-reentrancy.js new file mode 100644 index 0000000000..8added7f94 --- /dev/null +++ b/test/parallel/test-http2-rst-stream-reentrancy.js @@ -0,0 +1,68 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const http2 = require('http2'); +const net = require('net'); + +const PREFACE = Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'); + +function frame(type, flags, sid, payload = Buffer.alloc(0)) { + const header = Buffer.alloc(9); + header.writeUIntBE(payload.length, 0, 3); + header[3] = type; + header[4] = flags; + header.writeUInt32BE(sid & 0x7fffffff, 5); + return Buffer.concat([header, payload]); +} + +function goaway(lastStreamID, code) { + const payload = Buffer.alloc(8); + payload.writeUInt32BE(lastStreamID, 0); + payload.writeUInt32BE(code, 4); + return frame(7, 0, 0, payload); +} + +function headers(sid) { + return frame(1, 0x05, sid, Buffer.from([ + 0x82, // :method: GET + 0x86, // :scheme: http + 0x84, // :path: / + 0x41, 0x01, 0x78, // :authority: x + ])); +} + +const server = http2.createServer(); + +server.listen(0, common.mustCall(() => { + const socket = net.connect(server.address().port); + let sent = false; + + socket.on('connect', common.mustCall(() => { + socket.write(Buffer.concat([PREFACE, frame(4, 0, 0)])); + })); + + socket.on('error', () => {}); + + socket.on('data', common.mustCallAtLeast(() => { + if (sent) + return; + sent = true; + + socket.write(frame(4, 1, 0)); + socket.write(headers(1)); + + setImmediate(() => { + socket.write(Buffer.concat([ + goaway(0, 0), + headers(3), + headers(5), + headers(7), + ])); + setTimeout(() => socket.destroy(), common.platformTimeout(50)); + }); + })); + + socket.on('close', common.mustCall(() => server.close())); +})); From acaf4266b2be7958e3d7cb44b5ee1c2b96eca278 Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Mon, 20 Jul 2026 13:15:10 -0300 Subject: [PATCH 05/15] https: distinguish PFX object-array agent keys Signed-off-by: RafaelGSS PR-URL: https://github.com/nodejs-private/node-private/pull/930 Refs: https://hackerone.com/reports/3816840 CVE-ID: CVE-2026-56850 --- lib/https.js | 17 +++++- test/parallel/test-https-agent-getname.js | 44 ++++++++++++++ ...test-https-agent-pfx-object-array-reuse.js | 59 +++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-https-agent-pfx-object-array-reuse.js diff --git a/lib/https.js b/lib/https.js index 015c05b269..5bb65b1f9b 100644 --- a/lib/https.js +++ b/lib/https.js @@ -22,6 +22,7 @@ 'use strict'; const { + ArrayIsArray, ArrayPrototypeIndexOf, ArrayPrototypePush, ArrayPrototypeShift, @@ -467,6 +468,20 @@ ObjectSetPrototypeOf(Agent.prototype, HttpAgent.prototype); ObjectSetPrototypeOf(Agent, HttpAgent); Agent.prototype.createConnection = createConnection; +function getPfxAgentKey(pfx, passphrase) { + if (!ArrayIsArray(pfx)) + return pfx; + + let key = ''; + for (let i = 0; i < pfx.length; i++) { + const value = pfx[i]; + const raw = value?.buf || value; + const pass = value?.passphrase || passphrase; + key += `:${raw}:${pass}`; + } + return key; +} + /** * Gets a unique name for a set of options. * @param {{ @@ -502,7 +517,7 @@ Agent.prototype.getName = function getName(options = kEmptyObject) { name += ':'; if (options.pfx) - name += options.pfx; + name += getPfxAgentKey(options.pfx, options.passphrase); name += ':'; if (options.rejectUnauthorized !== undefined) diff --git a/test/parallel/test-https-agent-getname.js b/test/parallel/test-https-agent-getname.js index 2a13ab1c6f..8ead852b1d 100644 --- a/test/parallel/test-https-agent-getname.js +++ b/test/parallel/test-https-agent-getname.js @@ -6,6 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const https = require('https'); +const fixtures = require('../common/fixtures'); const agent = new https.Agent(); @@ -52,3 +53,46 @@ assert.strictEqual( '::secureProtocol:c,r,l:false:ecdhCurve:dhparam:0:sessionIdContext:' + '"sigalgs":privateKeyIdentifier:privateKeyEngine' ); + +{ + const baseOptions = { + host: '0.0.0.0', + port: 443, + }; + + const agent1 = fixtures.readKey('agent1.pfx'); + const agent6 = fixtures.readKey('agent6.pfx'); + + assert.notStrictEqual( + agent.getName({ + ...baseOptions, + pfx: [{ buf: agent1, passphrase: 'sample' }], + }), + agent.getName({ + ...baseOptions, + pfx: [{ buf: agent6, passphrase: 'sample' }], + }) + ); + + assert.notStrictEqual( + agent.getName({ + ...baseOptions, + pfx: [{ buf: agent1, passphrase: 'sample' }], + }), + agent.getName({ + ...baseOptions, + pfx: [{ buf: agent1, passphrase: 'different' }], + }) + ); + + assert.notStrictEqual( + agent.getName({ + ...baseOptions, + pfx: [{ __proto__: { buf: agent1, passphrase: 'sample' } }], + }), + agent.getName({ + ...baseOptions, + pfx: [{ __proto__: { buf: agent6, passphrase: 'sample' } }], + }) + ); +} diff --git a/test/parallel/test-https-agent-pfx-object-array-reuse.js b/test/parallel/test-https-agent-pfx-object-array-reuse.js new file mode 100644 index 0000000000..95134855e9 --- /dev/null +++ b/test/parallel/test-https-agent-pfx-object-array-reuse.js @@ -0,0 +1,59 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const https = require('https'); +const fixtures = require('../common/fixtures'); + +const server = https.createServer({ + key: fixtures.readKey('agent2-key.pem'), + cert: fixtures.readKey('agent2-cert.pem'), + requestCert: true, + rejectUnauthorized: false, +}, common.mustCall((req, res) => { + res.end(req.socket.getPeerCertificate().subject.CN); +}, 2)); + +server.listen(0, common.mustCall(async () => { + const agent = new https.Agent({ keepAlive: true, maxSockets: 1 }); + const port = server.address().port; + + const first = await request({ + agent, + port, + pfx: [{ buf: fixtures.readKey('agent1.pfx'), passphrase: 'sample' }], + }); + assert.strictEqual(first.body, 'agent1'); + assert.strictEqual(first.reusedSocket, false); + + const second = await request({ + agent, + port, + pfx: [{ buf: fixtures.readKey('agent10.pfx'), passphrase: 'sample' }], + }); + assert.strictEqual(second.body, 'agent10.example.com'); + assert.strictEqual(second.reusedSocket, false); + + agent.destroy(); + server.close(); +})); + +function request(options) { + return new Promise((resolve, reject) => { + const req = https.get({ + ...options, + rejectUnauthorized: false, + }, common.mustCall((res) => { + let body = ''; + res.setEncoding('utf8'); + res.on('data', (chunk) => body += chunk); + res.on('end', common.mustCall(() => { + resolve({ body, reusedSocket: req.reusedSocket }); + })); + })); + req.on('error', reject); + }); +} From ed18b9cc073f0b63268d6f2c84730b18e90fdd20 Mon Sep 17 00:00:00 2001 From: RafaelGSS Date: Fri, 26 Jun 2026 19:08:22 -0300 Subject: [PATCH 06/15] permission: check final report output path Refs: https://hackerone.com/reports/3815767 Signed-off-by: RafaelGSS PR-URL: https://github.com/nodejs-private/node-private/pull/926 CVE-ID: CVE-2026-58039 --- lib/internal/process/report.js | 10 ++- src/node_report.cc | 22 ++++--- .../test-permission-fs-write-report.js | 65 +++++++++++++++++++ 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/lib/internal/process/report.js b/lib/internal/process/report.js index 7b34af0e28..c383dc8cae 100644 --- a/lib/internal/process/report.js +++ b/lib/internal/process/report.js @@ -9,6 +9,7 @@ const { ERR_SYNTHETIC, } = require('internal/errors').codes; const { getValidatedPath } = require('internal/fs/utils'); +const { sep } = require('path'); const permission = require('internal/process/permission'); const { validateBoolean, @@ -29,7 +30,14 @@ const report = { } if (permission.isEnabled()) { - const resource = file ?? process.cwd(); + let resource = file; + if (resource !== undefined) { + const directory = nr.getDirectory(); + if (directory !== '') + resource = `${directory}${sep}${resource}`; + } else { + resource = process.cwd(); + } if (!permission.has('fs.write', resource)) { throw new ERR_ACCESS_DENIED( 'Access to this API has been restricted', diff --git a/src/node_report.cc b/src/node_report.cc index e1f4e30417..ead720dd02 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -851,13 +851,6 @@ std::string TriggerNodeReport(Isolate* isolate, filename = *DiagnosticFilename( env != nullptr ? env->thread_id() : 0, "report", "json"); } - if (env != nullptr) { - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, - permission::PermissionScope::kFileSystemWrite, - Environment::GetCwd(env->exec_path()), - filename); - } } // Open the report file stream for writing. Supports stdout/err, @@ -875,12 +868,21 @@ std::string TriggerNodeReport(Isolate* isolate, report_directory = per_process::cli_options->report_directory; } // Regular file. Append filename to directory path if one was specified + std::string pathname; if (report_directory.length() > 0) { - std::string pathname = report_directory + kPathSeparator + filename; - outfile.open(pathname, std::ios::out | std::ios::binary); + pathname = report_directory + kPathSeparator + filename; } else { - outfile.open(filename, std::ios::out | std::ios::binary); + pathname = filename; + } + + // We may not always be in a great state when generating a node report. + // Allow for the case where we don't have an env. + if (env != nullptr) { + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, pathname, ""); } + + outfile.open(pathname, std::ios::out | std::ios::binary); // Check for errors on the file open if (!outfile.is_open()) { std::cerr << "\nFailed to open Node.js report file: " << filename; diff --git a/test/parallel/test-permission-fs-write-report.js b/test/parallel/test-permission-fs-write-report.js index 595f83b268..728bc4d34c 100644 --- a/test/parallel/test-permission-fs-write-report.js +++ b/test/parallel/test-permission-fs-write-report.js @@ -23,6 +23,7 @@ if (!process.permission) { } const assert = require('assert'); +const fs = require('fs'); const path = require('path'); const tmpdir = require('../common/tmpdir'); @@ -73,3 +74,67 @@ spawnSyncAndExitWithoutError( ], { cwd: tmpdir.path } ); + +{ + const allowedDir = path.join(tmpdir.path, 'report-allowed'); + const deniedDir = path.join(tmpdir.path, 'report-denied'); + fs.mkdirSync(allowedDir); + fs.mkdirSync(deniedDir); + + const deniedFile = path.join(deniedDir, 'report.json'); + fs.writeFileSync(deniedFile, 'existing content'); + spawnSyncAndExitWithoutError( + process.execPath, + [ + '--permission', + '--allow-fs-read=*', + `--allow-fs-write=${allowedDir}`, + '-e', + ` + const assert = require('assert'); + process.report.directory = ${JSON.stringify(deniedDir)}; + assert.throws(() => { + process.report.writeReport('report.json'); + }, { + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: ${JSON.stringify(deniedFile)}, + }); + `, + ], + { cwd: allowedDir }, + ); + assert.strictEqual(fs.readFileSync(deniedFile, 'utf8'), 'existing content'); +} + +{ + const allowedDir = path.join(tmpdir.path, 'report-filename-allowed'); + const deniedDir = path.join(tmpdir.path, 'report-filename-denied'); + fs.mkdirSync(allowedDir); + fs.mkdirSync(deniedDir); + + const deniedFile = path.join(deniedDir, 'report.json'); + spawnSyncAndExitWithoutError( + process.execPath, + [ + '--permission', + '--allow-fs-read=*', + `--allow-fs-write=${allowedDir}`, + '-e', + ` + const assert = require('assert'); + process.report.directory = ${JSON.stringify(deniedDir)}; + process.report.filename = 'report.json'; + assert.throws(() => { + process.report.writeReport(); + }, { + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: ${JSON.stringify(deniedFile)}, + }); + `, + ], + { cwd: allowedDir }, + ); + assert.strictEqual(fs.existsSync(deniedFile), false); +} From 51123159fe863073d7dcaf5c88b23bad8aae1a62 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Tue, 23 Jun 2026 12:47:47 +0200 Subject: [PATCH 07/15] https: bind identity checks to session reuse PR-URL: https://github.com/nodejs-private/node-private/pull/934 Reviewed-By: Rafael Gonzaga CVE-ID: CVE-2026-58040 --- doc/api/https.md | 4 + lib/https.js | 44 ++++++- ...t-https-agent-checkserveridentity-reuse.js | 113 ++++++++++++++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-https-agent-checkserveridentity-reuse.js diff --git a/doc/api/https.md b/doc/api/https.md index b97e08cd5b..fa5c084b31 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -98,6 +98,10 @@ changes: See [`Session Resumption`][] for information about TLS session reuse. +Requests that specify a custom `checkServerIdentity` option are not eligible +for connection reuse or TLS session reuse by an `https.Agent`, unless the +`checkServerIdentity` option was specified when constructing the Agent. + #### Event: `'keylog'` +## 2026-07-29, Version 22.23.2-nsolid-v6.3.4 'Jod' + +### Commits + +* \[[`aa3a2bc8b0`](https://github.com/nodesource/nsolid/commit/aa3a2bc8b0)] - Merge tag 'v22.23.2' into node-v22.23.2-nsolid-v6.3.4-release (Santiago Gimeno) + ## 2026-07-22, Version 22.23.1-nsolid-v6.3.3 'Jod' ### Commits diff --git a/src/node_version.h b/src/node_version.h index a7b20ff2aa..405c3691d8 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -36,7 +36,7 @@ #define NSOLID_MINOR_VERSION 3 #define NSOLID_PATCH_VERSION 4 -#define NSOLID_VERSION_IS_RELEASE 0 +#define NSOLID_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)