Skip to content

Commit f52fbdb

Browse files
committed
chore: fixup sandboxed pointers patch
1 parent 8f9f30c commit f52fbdb

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

patches/node/support_v8_sandboxed_pointers.patch

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,89 @@ index 84a650885a79bc5c49efdc26f62ec8db48de775c..ba442937bf0d7831c9a84b5a57211e9f
234234
struct IsolateDataSerializeInfo {
235235
std::vector<SnapshotIndex> primitive_values;
236236
std::vector<PropInfo> template_values;
237+
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
238+
index 49df0b4284748effb27b05ecd69f05699dd8be75..eb104ab80fd2052d1523cb2f2ecdb6d23ac3be98 100644
239+
--- a/src/node_buffer.cc
240+
+++ b/src/node_buffer.cc
241+
@@ -81,6 +81,7 @@ using v8::SharedArrayBuffer;
242+
using v8::String;
243+
using v8::Uint32;
244+
using v8::Uint8Array;
245+
+using v8::Uint32Array;
246+
using v8::Value;
247+
248+
namespace {
249+
@@ -1243,6 +1244,45 @@ void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
250+
realm->set_buffer_prototype_object(proto);
251+
}
252+
253+
+void GetZeroFillToggle(const FunctionCallbackInfo<Value>& args) {
254+
+ Environment* env = Environment::GetCurrent(args);
255+
+ NodeArrayBufferAllocator* allocator = env->isolate_data()->node_allocator();
256+
+ Local<ArrayBuffer> ab;
257+
+ // It can be a nullptr when running inside an isolate where we
258+
+ // do not own the ArrayBuffer allocator.
259+
+ if (allocator == nullptr || env->isolate_data()->is_building_snapshot()) {
260+
+ // Create a dummy Uint32Array - the JS land can only toggle the C++ land
261+
+ // setting when the allocator uses our toggle. With this the toggle in JS
262+
+ // land results in no-ops.
263+
+ // When building a snapshot, just use a dummy toggle as well to avoid
264+
+ // introducing the dynamic external reference. We'll re-initialize the
265+
+ // toggle with a real one connected to the C++ allocator after snapshot
266+
+ // deserialization.
267+
+
268+
+ ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t));
269+
+ } else {
270+
+ // TODO(joyeecheung): save ab->GetBackingStore()->Data() in the Node.js
271+
+ // array buffer allocator and include it into the C++ toggle while the
272+
+ // Environment is still alive.
273+
+ uint32_t* zero_fill_field = allocator->zero_fill_field();
274+
+ std::unique_ptr<BackingStore> backing =
275+
+ ArrayBuffer::NewBackingStore(zero_fill_field,
276+
+ sizeof(*zero_fill_field),
277+
+ [](void*, size_t, void*) {},
278+
+ nullptr);
279+
+ ab = ArrayBuffer::New(env->isolate(), std::move(backing));
280+
+ }
281+
+
282+
+ if (ab->SetPrivate(env->context(),
283+
+ env->untransferable_object_private_symbol(),
284+
+ True(env->isolate()))
285+
+ .IsNothing()) {
286+
+ return;
287+
+ }
288+
+
289+
+ args.GetReturnValue().Set(Uint32Array::New(ab, 0, 1));
290+
+}
291+
+
292+
static void Btoa(const FunctionCallbackInfo<Value>& args) {
293+
CHECK_EQ(args.Length(), 1);
294+
Environment* env = Environment::GetCurrent(args);
295+
@@ -1420,7 +1460,7 @@ inline size_t CheckNumberToSize(Local<Value> number) {
296+
CHECK(value >= 0 && value < maxSize);
297+
size_t size = static_cast<size_t>(value);
298+
#ifdef V8_ENABLE_SANDBOX
299+
- CHECK_LE(size, kMaxSafeBufferSizeForSandbox);
300+
+ CHECK_LE(size, v8::internal::kMaxSafeBufferSizeForSandbox);
301+
#endif
302+
return size;
303+
}
304+
@@ -1638,6 +1678,7 @@ void Initialize(Local<Object> target,
305+
"utf8WriteStatic",
306+
SlowWriteString<UTF8>,
307+
&fast_write_string_utf8);
308+
+ SetMethod(context, target, "getZeroFillToggle", GetZeroFillToggle);
309+
}
310+
311+
} // anonymous namespace
312+
@@ -1686,6 +1727,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
313+
registry->Register(StringWrite<HEX>);
314+
registry->Register(StringWrite<UCS2>);
315+
registry->Register(StringWrite<UTF8>);
316+
+ registry->Register(GetZeroFillToggle);
317+
318+
registry->Register(CopyArrayBuffer);
319+
registry->Register(CreateUnsafeArrayBuffer);
237320
diff --git a/src/node_i18n.cc b/src/node_i18n.cc
238321
index 3c4f419aa29470b3280174b58680b9421b0340b5..3b24ad2a2316f89d98b067e2c13988f87a9a00d2 100644
239322
--- a/src/node_i18n.cc
@@ -274,6 +357,28 @@ index 3c4f419aa29470b3280174b58680b9421b0340b5..3b24ad2a2316f89d98b067e2c13988f8
274357
}
275358

276359
constexpr const char* EncodingName(const enum encoding encoding) {
360+
diff --git a/src/node_internals.h b/src/node_internals.h
361+
index 61a58b6ccfb26efefd6d3b61a1c8741f9550ae8d..29d1ecc2b209c9c3c2e956263ba2d57fb688b34c 100644
362+
--- a/src/node_internals.h
363+
+++ b/src/node_internals.h
364+
@@ -124,6 +124,9 @@ v8::MaybeLocal<v8::Object> InitializePrivateSymbols(
365+
366+
class NodeArrayBufferAllocator : public ArrayBufferAllocator {
367+
public:
368+
+ NodeArrayBufferAllocator();
369+
+ ~NodeArrayBufferAllocator() override;
370+
+ inline uint32_t* zero_fill_field() { return zero_fill_field_; }
371+
void* Allocate(size_t size) override; // Defined in src/node.cc
372+
void* AllocateUninitialized(size_t size) override;
373+
void Free(void* data, size_t size) override;
374+
@@ -140,6 +143,7 @@ class NodeArrayBufferAllocator : public ArrayBufferAllocator {
375+
}
376+
377+
private:
378+
+ uint32_t* zero_fill_field_ = nullptr; // Boolean but exposed as uint32 to JS land.
379+
std::atomic<size_t> total_mem_usage_ {0};
380+
381+
// Delegate to V8's allocator for compatibility with the V8 memory cage.
277382
diff --git a/src/node_serdes.cc b/src/node_serdes.cc
278383
index 00fcd4b6afccce47ff21c4447d9cd60f25c11835..5f96ee2051e5339456185efddb149c4d43093f31 100644
279384
--- a/src/node_serdes.cc

0 commit comments

Comments
 (0)