diff --git a/patches/node/support_v8_sandboxed_pointers.patch b/patches/node/support_v8_sandboxed_pointers.patch index cf53883006..b2c4252e62 100644 --- a/patches/node/support_v8_sandboxed_pointers.patch +++ b/patches/node/support_v8_sandboxed_pointers.patch @@ -234,6 +234,89 @@ index 84a650885a79bc5c49efdc26f62ec8db48de775c..ba442937bf0d7831c9a84b5a57211e9f struct IsolateDataSerializeInfo { std::vector primitive_values; std::vector template_values; +diff --git a/src/node_buffer.cc b/src/node_buffer.cc +index 49df0b4284748effb27b05ecd69f05699dd8be75..eb104ab80fd2052d1523cb2f2ecdb6d23ac3be98 100644 +--- a/src/node_buffer.cc ++++ b/src/node_buffer.cc +@@ -81,6 +81,7 @@ using v8::SharedArrayBuffer; + using v8::String; + using v8::Uint32; + using v8::Uint8Array; ++using v8::Uint32Array; + using v8::Value; + + namespace { +@@ -1243,6 +1244,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); +@@ -1420,7 +1460,7 @@ inline size_t CheckNumberToSize(Local number) { + CHECK(value >= 0 && value < maxSize); + size_t size = static_cast(value); + #ifdef V8_ENABLE_SANDBOX +- CHECK_LE(size, kMaxSafeBufferSizeForSandbox); ++ CHECK_LE(size, v8::internal::kMaxSafeBufferSizeForSandbox); + #endif + return size; + } +@@ -1638,6 +1678,7 @@ void Initialize(Local target, + "utf8WriteStatic", + SlowWriteString, + &fast_write_string_utf8); ++ SetMethod(context, target, "getZeroFillToggle", GetZeroFillToggle); + } + + } // anonymous namespace +@@ -1686,6 +1727,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 3c4f419aa29470b3280174b58680b9421b0340b5..3b24ad2a2316f89d98b067e2c13988f87a9a00d2 100644 --- a/src/node_i18n.cc @@ -274,6 +357,28 @@ index 3c4f419aa29470b3280174b58680b9421b0340b5..3b24ad2a2316f89d98b067e2c13988f8 } constexpr const char* EncodingName(const enum encoding encoding) { +diff --git a/src/node_internals.h b/src/node_internals.h +index 61a58b6ccfb26efefd6d3b61a1c8741f9550ae8d..29d1ecc2b209c9c3c2e956263ba2d57fb688b34c 100644 +--- a/src/node_internals.h ++++ b/src/node_internals.h +@@ -124,6 +124,9 @@ v8::MaybeLocal InitializePrivateSymbols( + + class NodeArrayBufferAllocator : public ArrayBufferAllocator { + public: ++ 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; + void Free(void* data, size_t size) override; +@@ -140,6 +143,7 @@ class NodeArrayBufferAllocator : public ArrayBufferAllocator { + } + + private: ++ 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 00fcd4b6afccce47ff21c4447d9cd60f25c11835..5f96ee2051e5339456185efddb149c4d43093f31 100644 --- a/src/node_serdes.cc