From bdb87f9dbb8077fb62911bb6695fdae183f6ad79 Mon Sep 17 00:00:00 2001 From: John Kleinschmidt Date: Tue, 20 Jan 2026 20:00:01 -0500 Subject: [PATCH] chore:remove zero-fill sandbox patch component xref https://github.com/electron/electron/pull/49452 --- .../api_remove_deprecated_getisolate.patch | 16 +- .../fix_remove_fastapitypedarray_usage.patch | 10 +- .../fix_replace_deprecated_setprototype.patch | 6 +- ...ch_cppgc_heap_on_v8_isolate_creation.patch | 6 +- ...t_setprototype_to_get_setprototypev2.patch | 8 +- .../node/support_v8_sandboxed_pointers.patch | 157 +----------------- 6 files changed, 26 insertions(+), 177 deletions(-) diff --git a/patches/node/api_remove_deprecated_getisolate.patch b/patches/node/api_remove_deprecated_getisolate.patch index 2dbd536899..10212b550b 100644 --- a/patches/node/api_remove_deprecated_getisolate.patch +++ b/patches/node/api_remove_deprecated_getisolate.patch @@ -6,10 +6,10 @@ Subject: Remove deprecated `GetIsolate` https://chromium-review.googlesource.com/c/v8/v8/+/6905244 diff --git a/src/api/environment.cc b/src/api/environment.cc -index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7c630fddf 100644 +index ceac508418f489a8077c1bc85a2feaf85bf60480..33827edce63c9fe08b52aea59571391a83853443 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc -@@ -654,7 +654,7 @@ std::unique_ptr MultiIsolatePlatform::Create( +@@ -646,7 +646,7 @@ std::unique_ptr MultiIsolatePlatform::Create( MaybeLocal GetPerContextExports(Local context, IsolateData* isolate_data) { @@ -18,7 +18,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 EscapableHandleScope handle_scope(isolate); Local global = context->Global(); -@@ -700,7 +700,7 @@ void ProtoThrower(const FunctionCallbackInfo& info) { +@@ -692,7 +692,7 @@ void ProtoThrower(const FunctionCallbackInfo& info) { // This runs at runtime, regardless of whether the context // is created from a snapshot. Maybe InitializeContextRuntime(Local context) { @@ -27,7 +27,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 HandleScope handle_scope(isolate); // When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path -@@ -779,7 +779,7 @@ Maybe InitializeContextRuntime(Local context) { +@@ -771,7 +771,7 @@ Maybe InitializeContextRuntime(Local context) { } Maybe InitializeBaseContextForSnapshot(Local context) { @@ -36,7 +36,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 HandleScope handle_scope(isolate); // Delete `Intl.v8BreakIterator` -@@ -804,7 +804,7 @@ Maybe InitializeBaseContextForSnapshot(Local context) { +@@ -796,7 +796,7 @@ Maybe InitializeBaseContextForSnapshot(Local context) { } Maybe InitializeMainContextForSnapshot(Local context) { @@ -45,7 +45,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 HandleScope handle_scope(isolate); // Initialize the default values. -@@ -822,7 +822,7 @@ Maybe InitializeMainContextForSnapshot(Local context) { +@@ -814,7 +814,7 @@ Maybe InitializeMainContextForSnapshot(Local context) { MaybeLocal InitializePrivateSymbols(Local context, IsolateData* isolate_data) { CHECK(isolate_data); @@ -54,7 +54,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 EscapableHandleScope scope(isolate); Context::Scope context_scope(context); -@@ -846,7 +846,7 @@ MaybeLocal InitializePrivateSymbols(Local context, +@@ -838,7 +838,7 @@ MaybeLocal InitializePrivateSymbols(Local context, MaybeLocal InitializePerIsolateSymbols(Local context, IsolateData* isolate_data) { CHECK(isolate_data); @@ -63,7 +63,7 @@ index 8e227ddd1be50c046a8cf2895a31d607eb7d31de..82f53bba29613de212f64be440ca20d7 EscapableHandleScope scope(isolate); Context::Scope context_scope(context); -@@ -872,7 +872,7 @@ MaybeLocal InitializePerIsolateSymbols(Local context, +@@ -864,7 +864,7 @@ MaybeLocal InitializePerIsolateSymbols(Local context, Maybe InitializePrimordials(Local context, IsolateData* isolate_data) { // Run per-context JS files. diff --git a/patches/node/fix_remove_fastapitypedarray_usage.patch b/patches/node/fix_remove_fastapitypedarray_usage.patch index c72c8e5029..5076a71a9a 100644 --- a/patches/node/fix_remove_fastapitypedarray_usage.patch +++ b/patches/node/fix_remove_fastapitypedarray_usage.patch @@ -48,7 +48,7 @@ index fe669d40c31a29334b047b9cfee3067f64ef0a7b..9e5de7bbe574add017cd12ee091304d0 static CFunction fast_timing_safe_equal(CFunction::Make(FastTimingSafeEqual)); diff --git a/src/node_buffer.cc b/src/node_buffer.cc -index 45c6b4cf19f7b336891dae3cd84d698507227d9e..fc7ccd647585fe3b96648ccd83ef49d93c9c4438 100644 +index b9f0c97938203b4652780a7d707c5e83319330b0..8a5b6b57321c2843a965a7e51b2ebed991a1e424 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -44,6 +44,14 @@ @@ -74,7 +74,7 @@ index 45c6b4cf19f7b336891dae3cd84d698507227d9e..fc7ccd647585fe3b96648ccd83ef49d9 using v8::FunctionCallbackInfo; using v8::Global; using v8::HandleScope; -@@ -584,19 +591,24 @@ void SlowCopy(const FunctionCallbackInfo& args) { +@@ -583,19 +590,24 @@ void SlowCopy(const FunctionCallbackInfo& args) { // Assume caller has properly validated args. uint32_t FastCopy(Local receiver, @@ -107,7 +107,7 @@ index 45c6b4cf19f7b336891dae3cd84d698507227d9e..fc7ccd647585fe3b96648ccd83ef49d9 return to_copy; } -@@ -865,19 +877,17 @@ void Compare(const FunctionCallbackInfo &args) { +@@ -864,19 +876,17 @@ void Compare(const FunctionCallbackInfo &args) { } int32_t FastCompare(v8::Local, @@ -135,7 +135,7 @@ index 45c6b4cf19f7b336891dae3cd84d698507227d9e..fc7ccd647585fe3b96648ccd83ef49d9 } static v8::CFunction fast_compare(v8::CFunction::Make(FastCompare)); -@@ -1149,14 +1159,13 @@ void SlowIndexOfNumber(const FunctionCallbackInfo& args) { +@@ -1148,14 +1158,13 @@ void SlowIndexOfNumber(const FunctionCallbackInfo& args) { } int32_t FastIndexOfNumber(v8::Local, @@ -153,7 +153,7 @@ index 45c6b4cf19f7b336891dae3cd84d698507227d9e..fc7ccd647585fe3b96648ccd83ef49d9 } static v8::CFunction fast_index_of_number( -@@ -1550,21 +1559,31 @@ void SlowWriteString(const FunctionCallbackInfo& args) { +@@ -1510,21 +1519,31 @@ void SlowWriteString(const FunctionCallbackInfo& args) { template uint32_t FastWriteString(Local receiver, diff --git a/patches/node/fix_replace_deprecated_setprototype.patch b/patches/node/fix_replace_deprecated_setprototype.patch index 26a36c6f5e..b2e8c47115 100644 --- a/patches/node/fix_replace_deprecated_setprototype.patch +++ b/patches/node/fix_replace_deprecated_setprototype.patch @@ -9,10 +9,10 @@ This is already applied in newer versions of Node so we can drop this patch once we upgrade to v23. diff --git a/src/api/environment.cc b/src/api/environment.cc -index 0a358735c331767e8eb563a80e9aaccfb544c27b..d7d18d5fcbf008ac131db189a141315af4f6410b 100644 +index 79327877b0f34cbafb3efcc21617027d4011f806..8a12475857135bd3e904610b7eb887c397c8e73c 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc -@@ -835,7 +835,7 @@ MaybeLocal InitializePrivateSymbols(Local context, +@@ -827,7 +827,7 @@ MaybeLocal InitializePrivateSymbols(Local context, Local private_symbols_object; if (!private_symbols->NewInstance(context).ToLocal(&private_symbols_object) || @@ -21,7 +21,7 @@ index 0a358735c331767e8eb563a80e9aaccfb544c27b..d7d18d5fcbf008ac131db189a141315a .IsNothing()) { return MaybeLocal(); } -@@ -861,7 +861,7 @@ MaybeLocal InitializePerIsolateSymbols(Local context, +@@ -853,7 +853,7 @@ MaybeLocal InitializePerIsolateSymbols(Local context, Local per_isolate_symbols_object; if (!per_isolate_symbols->NewInstance(context).ToLocal( &per_isolate_symbols_object) || diff --git a/patches/node/refactor_attach_cppgc_heap_on_v8_isolate_creation.patch b/patches/node/refactor_attach_cppgc_heap_on_v8_isolate_creation.patch index e8a1918364..e6fb5d3c8e 100644 --- a/patches/node/refactor_attach_cppgc_heap_on_v8_isolate_creation.patch +++ b/patches/node/refactor_attach_cppgc_heap_on_v8_isolate_creation.patch @@ -18,10 +18,10 @@ This can be removed when Node.js upgrades to a version of V8 containing CLs from the above issue. diff --git a/src/api/environment.cc b/src/api/environment.cc -index cb37fa080fc8e8d524cfa2758c4a8c2c5652324d..8e227ddd1be50c046a8cf2895a31d607eb7d31de 100644 +index fd71ceac65ccef1d2832b45b0b5612877cee22c1..ceac508418f489a8077c1bc85a2feaf85bf60480 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc -@@ -316,6 +316,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params, +@@ -308,6 +308,10 @@ Isolate* NewIsolate(Isolate::CreateParams* params, MultiIsolatePlatform* platform, const SnapshotData* snapshot_data, const IsolateSettings& settings) { @@ -32,7 +32,7 @@ index cb37fa080fc8e8d524cfa2758c4a8c2c5652324d..8e227ddd1be50c046a8cf2895a31d607 Isolate* isolate = Isolate::Allocate(); if (isolate == nullptr) return nullptr; -@@ -359,9 +363,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator, +@@ -351,9 +355,12 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator, uv_loop_t* event_loop, MultiIsolatePlatform* platform, const EmbedderSnapshotData* snapshot_data, diff --git a/patches/node/src_switch_from_get_setprototype_to_get_setprototypev2.patch b/patches/node/src_switch_from_get_setprototype_to_get_setprototypev2.patch index 3e5a2a15eb..725fee9a2c 100644 --- a/patches/node/src_switch_from_get_setprototype_to_get_setprototypev2.patch +++ b/patches/node/src_switch_from_get_setprototype_to_get_setprototypev2.patch @@ -10,10 +10,10 @@ Reviewed-By: Moshe Atlow Reviewed-By: James M Snell diff --git a/src/api/environment.cc b/src/api/environment.cc -index 82f53bba29613de212f64be440ca20d7c630fddf..0a358735c331767e8eb563a80e9aaccfb544c27b 100644 +index 33827edce63c9fe08b52aea59571391a83853443..79327877b0f34cbafb3efcc21617027d4011f806 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc -@@ -886,7 +886,7 @@ Maybe InitializePrimordials(Local context, +@@ -878,7 +878,7 @@ Maybe InitializePrimordials(Local context, CHECK(!exports->Has(context, primordials_string).FromJust()); Local primordials = Object::New(isolate); @@ -51,10 +51,10 @@ index 7b2efa49468c0bed2f5935552addd3ab37d0a50b..413db3ed9b88d7b7fb2ac6dd1153dade return GET_RETURN_STATUS(env); } diff --git a/src/node_buffer.cc b/src/node_buffer.cc -index fc7ccd647585fe3b96648ccd83ef49d93c9c4438..aeacdcd13422aeb0fa4b1e234851d7b52f5de116 100644 +index 8a5b6b57321c2843a965a7e51b2ebed991a1e424..e844fe6cb33acefd075516e675075421ad5c3cff 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc -@@ -284,8 +284,9 @@ MaybeLocal New(Environment* env, +@@ -283,8 +283,9 @@ MaybeLocal New(Environment* env, size_t length) { CHECK(!env->buffer_prototype_object().IsEmpty()); Local ui = Uint8Array::New(ab, byte_offset, length); diff --git a/patches/node/support_v8_sandboxed_pointers.patch b/patches/node/support_v8_sandboxed_pointers.patch index ac712f94f2..cf22647d1d 100644 --- a/patches/node/support_v8_sandboxed_pointers.patch +++ b/patches/node/support_v8_sandboxed_pointers.patch @@ -6,63 +6,6 @@ Subject: support V8 sandboxed pointers This refactors several allocators to allocate within the V8 memory cage, allowing them to be compatible with the V8_SANDBOXED_POINTERS feature. -diff --git a/src/api/environment.cc b/src/api/environment.cc -index fd71ceac65ccef1d2832b45b0b5612877cee22c1..cb37fa080fc8e8d524cfa2758c4a8c2c5652324d 100644 ---- a/src/api/environment.cc -+++ b/src/api/environment.cc -@@ -106,6 +106,14 @@ MaybeLocal PrepareStackTraceCallback(Local context, - return result; - } - -+NodeArrayBufferAllocator::NodeArrayBufferAllocator() { -+ zero_fill_field_ = static_cast(allocator_->Allocate(sizeof(*zero_fill_field_))); -+} -+ -+NodeArrayBufferAllocator::~NodeArrayBufferAllocator() { -+ allocator_->Free(zero_fill_field_, sizeof(*zero_fill_field_)); -+} -+ - void* NodeArrayBufferAllocator::Allocate(size_t size) { - void* ret; - if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) -diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc -index f23cedf4f2449d8edc9a8de1b70332e75d693cdd..976653dd1e9363e046788fc3419a9b649ceb2ea4 100644 ---- a/src/crypto/crypto_dh.cc -+++ b/src/crypto/crypto_dh.cc -@@ -55,13 +55,32 @@ void DiffieHellman::MemoryInfo(MemoryTracker* tracker) const { - - namespace { - MaybeLocal DataPointerToBuffer(Environment* env, DataPointer&& data) { -+#if defined(V8_ENABLE_SANDBOX) -+ std::unique_ptr backing; -+ if (data.size() > 0) { -+ std::unique_ptr allocator(ArrayBuffer::Allocator::NewDefaultAllocator()); -+ void* v8_data = allocator->Allocate(data.size()); -+ CHECK(v8_data); -+ memcpy(v8_data, data.get(), data.size()); -+ backing = ArrayBuffer::NewBackingStore( -+ v8_data, -+ data.size(), -+ [](void* data, size_t length, void*) { -+ std::unique_ptr allocator(ArrayBuffer::Allocator::NewDefaultAllocator()); -+ allocator->Free(data, length); -+ }, nullptr); -+ } else { -+ NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); -+ backing = v8::ArrayBuffer::NewBackingStore(env->isolate(), data.size()); -+ } -+#else - auto backing = ArrayBuffer::NewBackingStore( - data.get(), - data.size(), - [](void* data, size_t len, void* ptr) { DataPointer free_me(data, len); }, - nullptr); - data.release(); -- -+#endif - auto ab = ArrayBuffer::New(env->isolate(), std::move(backing)); - return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local()); - } diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 4505786745c54a529f904d5e7813a86204e0a78b..eab18ab9888e2f7c0757fefab80505d8c99dc742 100644 --- a/src/crypto/crypto_util.cc @@ -189,64 +132,10 @@ index f616223cfb0f6e10f7cf57ada9704316bde2797e..eb6dad44a49d997097c8fb5009eeb60a Local ret; if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {}; diff --git a/src/node_buffer.cc b/src/node_buffer.cc -index 357dc5f6d1c1c2d3756a94c1326b0502403e1eaf..45c6b4cf19f7b336891dae3cd84d698507227d9e 100644 +index 357dc5f6d1c1c2d3756a94c1326b0502403e1eaf..b9f0c97938203b4652780a7d707c5e83319330b0 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc -@@ -78,6 +78,7 @@ using v8::SharedArrayBuffer; - using v8::String; - using v8::Uint32; - using v8::Uint8Array; -+using v8::Uint32Array; - using v8::Value; - - namespace { -@@ -1228,6 +1229,45 @@ void SetBufferPrototype(const FunctionCallbackInfo& args) { - realm->set_buffer_prototype_object(proto); - } - -+void GetZeroFillToggle(const FunctionCallbackInfo& args) { -+ Environment* env = Environment::GetCurrent(args); -+ NodeArrayBufferAllocator* allocator = env->isolate_data()->node_allocator(); -+ Local ab; -+ // It can be a nullptr when running inside an isolate where we -+ // do not own the ArrayBuffer allocator. -+ if (allocator == nullptr || env->isolate_data()->is_building_snapshot()) { -+ // Create a dummy Uint32Array - the JS land can only toggle the C++ land -+ // setting when the allocator uses our toggle. With this the toggle in JS -+ // land results in no-ops. -+ // When building a snapshot, just use a dummy toggle as well to avoid -+ // introducing the dynamic external reference. We'll re-initialize the -+ // toggle with a real one connected to the C++ allocator after snapshot -+ // deserialization. -+ -+ ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t)); -+ } else { -+ // TODO(joyeecheung): save ab->GetBackingStore()->Data() in the Node.js -+ // array buffer allocator and include it into the C++ toggle while the -+ // Environment is still alive. -+ uint32_t* zero_fill_field = allocator->zero_fill_field(); -+ std::unique_ptr backing = -+ ArrayBuffer::NewBackingStore(zero_fill_field, -+ sizeof(*zero_fill_field), -+ [](void*, size_t, void*) {}, -+ nullptr); -+ ab = ArrayBuffer::New(env->isolate(), std::move(backing)); -+ } -+ -+ if (ab->SetPrivate(env->context(), -+ env->untransferable_object_private_symbol(), -+ True(env->isolate())) -+ .IsNothing()) { -+ return; -+ } -+ -+ args.GetReturnValue().Set(Uint32Array::New(ab, 0, 1)); -+} -+ - static void Btoa(const FunctionCallbackInfo& args) { - CHECK_EQ(args.Length(), 1); - Environment* env = Environment::GetCurrent(args); -@@ -1412,7 +1452,7 @@ inline size_t CheckNumberToSize(Local number) { +@@ -1412,7 +1412,7 @@ inline size_t CheckNumberToSize(Local number) { CHECK(value >= 0 && value < maxSize); size_t size = static_cast(value); #ifdef V8_ENABLE_SANDBOX @@ -255,7 +144,7 @@ index 357dc5f6d1c1c2d3756a94c1326b0502403e1eaf..45c6b4cf19f7b336891dae3cd84d6985 #endif return size; } -@@ -1437,7 +1477,7 @@ void CreateUnsafeArrayBuffer(const FunctionCallbackInfo& args) { +@@ -1437,7 +1437,7 @@ void CreateUnsafeArrayBuffer(const FunctionCallbackInfo& args) { buf = ArrayBuffer::New(isolate, size); } else { std::unique_ptr store = @@ -264,22 +153,6 @@ index 357dc5f6d1c1c2d3756a94c1326b0502403e1eaf..45c6b4cf19f7b336891dae3cd84d6985 if (!store) { return env->ThrowRangeError("Array buffer allocation failed"); } -@@ -1615,6 +1655,7 @@ void Initialize(Local target, - "utf8WriteStatic", - SlowWriteString, - &fast_write_string_utf8); -+ SetMethod(context, target, "getZeroFillToggle", GetZeroFillToggle); - } - - } // anonymous namespace -@@ -1663,6 +1704,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { - registry->Register(StringWrite); - registry->Register(StringWrite); - registry->Register(StringWrite); -+ registry->Register(GetZeroFillToggle); - - registry->Register(CopyArrayBuffer); - registry->Register(CreateUnsafeArrayBuffer); diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 6be3920632b25db450025ebab6a2636e4811cdbe..b49916d2b5fc5e58cf3fb67329430fd3df8fb813 100644 --- a/src/node_i18n.cc @@ -320,30 +193,6 @@ index 6be3920632b25db450025ebab6a2636e4811cdbe..b49916d2b5fc5e58cf3fb67329430fd3 } constexpr const char* EncodingName(const enum encoding encoding) { -diff --git a/src/node_internals.h b/src/node_internals.h -index 12ea72b61b0a5e194207bb369dfed4b8667107cb..64442215714a98f648971e517ddd9c77e38fe3f2 100644 ---- a/src/node_internals.h -+++ b/src/node_internals.h -@@ -121,7 +121,9 @@ v8::MaybeLocal InitializePrivateSymbols( - - class NodeArrayBufferAllocator : public ArrayBufferAllocator { - public: -- inline uint32_t* zero_fill_field() { return &zero_fill_field_; } -+ NodeArrayBufferAllocator(); -+ ~NodeArrayBufferAllocator() override; -+ inline uint32_t* zero_fill_field() { return zero_fill_field_; } - - void* Allocate(size_t size) override; // Defined in src/node.cc - void* AllocateUninitialized(size_t size) override; -@@ -139,7 +141,7 @@ class NodeArrayBufferAllocator : public ArrayBufferAllocator { - } - - private: -- uint32_t zero_fill_field_ = 1; // Boolean but exposed as uint32 to JS land. -+ uint32_t* zero_fill_field_ = nullptr; // Boolean but exposed as uint32 to JS land. - std::atomic total_mem_usage_ {0}; - - // Delegate to V8's allocator for compatibility with the V8 memory cage. diff --git a/src/node_serdes.cc b/src/node_serdes.cc index c55a2e28066147ae5ca5def10ec76ccc03c634b4..c54183c72944989219b6437c9e571a3f7f3f8dd5 100644 --- a/src/node_serdes.cc