@@ -34,6 +34,7 @@ using ncrypto::EnginePointer;
3434using ncrypto::SSLPointer;
3535using v8::ArrayBuffer;
3636using v8::BackingStore;
37+ using v8::BackingStoreInitializationMode;
3738using v8::BigInt;
3839using v8::Context;
3940using v8::EscapableHandleScope;
@@ -339,16 +340,27 @@ ByteSource& ByteSource::operator=(ByteSource&& other) noexcept {
339340 return *this ;
340341}
341342
342- std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore () {
343+ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore (
344+ Environment* env) {
343345 // It's ok for allocated_data_ to be nullptr but
344346 // only if size_ is zero.
345347 CHECK_IMPLIES (size_ > 0 , allocated_data_ != nullptr );
348+ #if defined(V8_ENABLE_SANDBOX)
349+ // If the v8 sandbox is enabled, then all array buffers must be allocated
350+ // via the isolate. External buffers are not allowed. So, instead of wrapping
351+ // the allocated data we'll copy it instead.
352+ std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore (
353+ env->isolate (), size (), BackingStoreInitializationMode::kUninitialized );
354+ memcpy (ptr->Data (), allocated_data_, size ());
355+ OPENSSL_clear_free (allocated_data_, size_);
356+ #else
346357 std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore (
347358 allocated_data_,
348359 size (),
349360 [](void * data, size_t length, void * deleter_data) {
350361 OPENSSL_clear_free (deleter_data, length);
351362 }, allocated_data_);
363+ #endif
352364 CHECK (ptr);
353365 allocated_data_ = nullptr ;
354366 data_ = nullptr ;
@@ -357,7 +369,7 @@ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
357369}
358370
359371Local<ArrayBuffer> ByteSource::ToArrayBuffer (Environment* env) {
360- std::unique_ptr<BackingStore> store = ReleaseToBackingStore ();
372+ std::unique_ptr<BackingStore> store = ReleaseToBackingStore (env );
361373 return ArrayBuffer::New (env->isolate (), std::move (store));
362374}
363375
@@ -648,8 +660,19 @@ namespace {
648660// using OPENSSL_malloc. However, if the secure heap is
649661// initialized, SecureBuffer will automatically use it.
650662void SecureBuffer (const FunctionCallbackInfo<Value>& args) {
651- CHECK (args[0 ]->IsUint32 ());
652663 Environment* env = Environment::GetCurrent (args);
664+ #if defined(V8_ENABLE_SANDBOX)
665+ // The v8 sandbox is enabled, so we cannot use the secure heap because
666+ // the sandbox requires that all array buffers be allocated via the isolate.
667+ // That is fundamentally incompatible with the secure heap which allocates
668+ // in openssl's secure heap area. Instead we'll just throw an error here.
669+ //
670+ // That said, we really shouldn't get here in the first place since the
671+ // option to enable the secure heap is only available when the sandbox
672+ // is disabled.
673+ THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION (env);
674+ #else
675+ CHECK (args[0 ]->IsUint32 ());
653676 uint32_t len = args[0 ].As <Uint32>()->Value ();
654677
655678 auto data = DataPointer::SecureAlloc (len);
@@ -676,6 +699,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
676699
677700 Local<ArrayBuffer> buffer = ArrayBuffer::New (env->isolate (), store);
678701 args.GetReturnValue ().Set (Uint8Array::New (buffer, 0 , len));
702+ #endif
679703}
680704
681705void SecureHeapUsed (const FunctionCallbackInfo<Value>& args) {
0 commit comments