@@ -34,6 +34,8 @@ using ncrypto::EnginePointer;
34
34
using ncrypto::SSLPointer;
35
35
using v8::ArrayBuffer;
36
36
using v8::BackingStore;
37
+
using v8::BackingStoreInitializationMode;
38
+
using v8::BackingStoreOnFailureMode;
37
39
using v8::BigInt;
38
40
using v8::Context;
39
41
using v8::EscapableHandleScope;
@@ -339,16 +341,37 @@ ByteSource& ByteSource::operator=(ByteSource&& other) noexcept {
339
341
return *this;
340
342
}
341
343
342
-
std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
344
+
std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore(
345
+
Environment* env) {
343
346
// It's ok for allocated_data_ to be nullptr but
344
347
// only if size_ is zero.
345
348
CHECK_IMPLIES(size_ > 0, allocated_data_ != nullptr);
349
+
#ifdef V8_ENABLE_SANDBOX
350
+
// If the v8 sandbox is enabled, then all array buffers must be allocated
351
+
// via the isolate. External buffers are not allowed. So, instead of wrapping
352
+
// the allocated data we'll copy it instead.
353
+
354
+
// TODO(@jasnell): It would be nice to use an abstracted utility to do this
355
+
// branch instead of duplicating the V8_ENABLE_SANDBOX check each time.
356
+
std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
357
+
env->isolate(),
358
+
size(),
359
+
BackingStoreInitializationMode::kUninitialized,
360
+
BackingStoreOnFailureMode::kReturnNull);
361
+
if (!ptr) {
362
+
THROW_ERR_MEMORY_ALLOCATION_FAILED(env);
363
+
return nullptr;
364
+
}
365
+
memcpy(ptr->Data(), allocated_data_, size());
366
+
OPENSSL_clear_free(allocated_data_, size_);
367
+
#else
346
368
std::unique_ptr<BackingStore> ptr = ArrayBuffer::NewBackingStore(
347
369
allocated_data_,
348
370
size(),
349
371
[](void* data, size_t length, void* deleter_data) {
350
372
OPENSSL_clear_free(deleter_data, length);
351
373
}, allocated_data_);
374
+
#endif // V8_ENABLE_SANDBOX
352
375
CHECK(ptr);
353
376
allocated_data_ = nullptr;
354
377
data_ = nullptr;
@@ -357,7 +380,7 @@ std::unique_ptr<BackingStore> ByteSource::ReleaseToBackingStore() {
357
380
}
358
381
359
382
Local<ArrayBuffer> ByteSource::ToArrayBuffer(Environment* env) {
360
-
std::unique_ptr<BackingStore> store = ReleaseToBackingStore();
383
+
std::unique_ptr<BackingStore> store = ReleaseToBackingStore(env);
361
384
return ArrayBuffer::New(env->isolate(), std::move(store));
362
385
}
363
386
@@ -648,8 +671,19 @@ namespace {
648
671
// using OPENSSL_malloc. However, if the secure heap is
649
672
// initialized, SecureBuffer will automatically use it.
650
673
void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
651
-
CHECK(args[0]->IsUint32());
652
674
Environment* env = Environment::GetCurrent(args);
675
+
#ifdef V8_ENABLE_SANDBOX
676
+
// The v8 sandbox is enabled, so we cannot use the secure heap because
677
+
// the sandbox requires that all array buffers be allocated via the isolate.
678
+
// That is fundamentally incompatible with the secure heap which allocates
679
+
// in openssl's secure heap area. Instead we'll just throw an error here.
680
+
//
681
+
// That said, we really shouldn't get here in the first place since the
682
+
// option to enable the secure heap is only available when the sandbox
683
+
// is disabled.
684
+
UNREACHABLE();
685
+
#else
686
+
CHECK(args[0]->IsUint32());
653
687
uint32_t len = args[0].As<Uint32>()->Value();
654
688
655
689
auto data = DataPointer::SecureAlloc(len);
@@ -676,6 +710,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
676
710
677
711
Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
678
712
args.GetReturnValue().Set(Uint8Array::New(buffer, 0, len));
713
+
#endif // V8_ENABLE_SANDBOX
679
714
}
680
715
681
716
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4