| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,8 @@ using ncrypto::DHPointer; | |||
| 22 | 22 | using ncrypto::EVPKeyCtxPointer; | |
| 23 | 23 | using ncrypto::EVPKeyPointer; | |
| 24 | 24 | using v8::ArrayBuffer; | |
| 25 | + using v8::BackingStoreInitializationMode; | ||
| 26 | + using v8::BackingStoreOnFailureMode; | ||
| 25 | 27 | using v8::ConstructorBehavior; | |
| 26 | 28 | using v8::Context; | |
| 27 | 29 | using v8::DontDelete; | |
@@ -58,6 +60,20 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) { | |||
| 58 | 60 | struct Flag { | |
| 59 | 61 | bool secure; | |
| 60 | 62 | }; | |
| 63 | + #ifdef V8_ENABLE_SANDBOX | ||
| 64 | + auto backing = ArrayBuffer::NewBackingStore( | ||
| 65 | + env->isolate(), | ||
| 66 | + data.size(), | ||
| 67 | + BackingStoreInitializationMode::kUninitialized, | ||
| 68 | + BackingStoreOnFailureMode::kReturnNull); | ||
| 69 | + if (!backing) { | ||
| 70 | + THROW_ERR_MEMORY_ALLOCATION_FAILED(env); | ||
| 71 | + return MaybeLocal<Value>(); | ||
| 72 | + } | ||
| 73 | + if (data.size() > 0) { | ||
| 74 | + memcpy(backing->Data(), data.get(), data.size()); | ||
| 75 | + } | ||
| 76 | + #else | ||
| 61 | 77 | auto backing = ArrayBuffer::NewBackingStore( | |
| 62 | 78 | data.get(), | |
| 63 | 79 | data.size(), | |
@@ -67,6 +83,7 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) { | |||
| 67 | 83 | }, | |
| 68 | 84 | new Flag{data.isSecure()}); | |
| 69 | 85 | data.release(); | |
| 86 | + #endif // V8_ENABLE_SANDBOX | ||
| 70 | 87 | ||
| 71 | 88 | auto ab = ArrayBuffer::New(env->isolate(), std::move(backing)); | |
| 72 | 89 | return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -185,7 +185,7 @@ class ByteSource final { | |||
| 185 | 185 | // Creates a v8::BackingStore that takes over responsibility for | |
| 186 | 186 | // any allocated data. The ByteSource will be reset with size = 0 | |
| 187 | 187 | // after being called. | |
| 188 | - std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(); | ||
| 188 | + std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(Environment* env); | ||
| 189 | 189 | ||
| 190 | 190 | v8::Local<v8::ArrayBuffer> ToArrayBuffer(Environment* env); | |
| 191 | 191 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,6 +29,7 @@ using v8::Array; | |||
| 29 | 29 | using v8::ArrayBuffer; | |
| 30 | 30 | using v8::ArrayBufferView; | |
| 31 | 31 | using v8::BackingStoreInitializationMode; | |
| 32 | + using v8::BackingStoreOnFailureMode; | ||
| 32 | 33 | using v8::Boolean; | |
| 33 | 34 | using v8::Context; | |
| 34 | 35 | using v8::Date; | |
@@ -131,13 +132,29 @@ MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) { | |||
| 131 | 132 | if (bio == nullptr || !*bio) [[unlikely]] | |
| 132 | 133 | return {}; | |
| 133 | 134 | BUF_MEM* mem = *bio; | |
| 135 | + #ifdef V8_ENABLE_SANDBOX | ||
| 136 | + // If the v8 sandbox is enabled, then all array buffers must be allocated | ||
| 137 | + // via the isolate. External buffers are not allowed. So, instead of wrapping | ||
| 138 | + // the BIOPointer we'll copy it instead. | ||
| 139 | + auto backing = ArrayBuffer::NewBackingStore( | ||
| 140 | + env->isolate(), | ||
| 141 | + mem->length, | ||
| 142 | + BackingStoreInitializationMode::kUninitialized, | ||
| 143 | + BackingStoreOnFailureMode::kReturnNull); | ||
| 144 | + if (!backing) { | ||
| 145 | + THROW_ERR_MEMORY_ALLOCATION_FAILED(env); | ||
| 146 | + return MaybeLocal<Value>(); | ||
| 147 | + } | ||
| 148 | + memcpy(backing->Data(), mem->data, mem->length); | ||
| 149 | + #else | ||
| 134 | 150 | auto backing = ArrayBuffer::NewBackingStore( | |
| 135 | 151 | mem->data, | |
| 136 | 152 | mem->length, | |
| 137 | 153 | [](void*, size_t, void* data) { | |
| 138 | 154 | BIOPointer free_me(static_cast<BIO*>(data)); | |
| 139 | 155 | }, | |
| 140 | 156 | bio->release()); | |
| 157 | + #endif // V8_ENABLE_SANDBOX | ||
| 141 | 158 | auto ab = ArrayBuffer::New(env->isolate(), std::move(backing)); | |
| 142 | 159 | Local<Value> ret; | |
| 143 | 160 | if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {}; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -114,7 +114,7 @@ napi_status NewExternalString(napi_env env, | |||
| 114 | 114 | CHECK_NEW_STRING_ARGS(env, str, length, result); | |
| 115 | 115 | ||
| 116 | 116 | napi_status status; | |
| 117 | - #if defined(V8_ENABLE_SANDBOX) | ||
| 117 | + #ifdef V8_ENABLE_SANDBOX | ||
| 118 | 118 | status = create_api(env, str, length, result); | |
| 119 | 119 | if (status == napi_ok) { | |
| 120 | 120 | if (copied != nullptr) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1056,9 +1056,9 @@ napi_create_external_buffer(napi_env env, | |||
| 1056 | 1056 | NAPI_PREAMBLE(env); | |
| 1057 | 1057 | CHECK_ARG(env, result); | |
| 1058 | 1058 | ||
| 1059 | - #if defined(V8_ENABLE_SANDBOX) | ||
| 1059 | + #ifdef V8_ENABLE_SANDBOX | ||
| 1060 | 1060 | return napi_set_last_error(env, napi_no_external_buffers_allowed); | |
| 1061 | - #endif | ||
| 1061 | + #endif // V8_ENABLE_SANDBOX | ||
| 1062 | 1062 | ||
| 1063 | 1063 | v8::Isolate* isolate = env->isolate; | |
| 1064 | 1064 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -81,6 +81,8 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors, | |||
| 81 | 81 | } | |
| 82 | 82 | ||
| 83 | 83 | // Any value less than 2 disables use of the secure heap. | |
| 84 | + #ifndef V8_ENABLE_SANDBOX | ||
| 85 | + // The secure heap is not supported when V8_ENABLE_SANDBOX is enabled. | ||
| 84 | 86 | if (secure_heap >= 2) { | |
| 85 | 87 | if ((secure_heap & (secure_heap - 1)) != 0) | |
| 86 | 88 | errors->push_back("--secure-heap must be a power of 2"); | |
@@ -93,6 +95,7 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors, | |||
| 93 | 95 | if ((secure_heap_min & (secure_heap_min - 1)) != 0) | |
| 94 | 96 | errors->push_back("--secure-heap-min must be a power of 2"); | |
| 95 | 97 | } | |
| 98 | + #endif // V8_ENABLE_SANDBOX | ||
| 96 | 99 | #endif // HAVE_OPENSSL | |
| 97 | 100 | ||
| 98 | 101 | if (use_largepages != "off" && | |
@@ -1173,6 +1176,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( | |||
| 1173 | 1176 | "force FIPS crypto (cannot be disabled)", | |
| 1174 | 1177 | &PerProcessOptions::force_fips_crypto, | |
| 1175 | 1178 | kAllowedInEnvvar); | |
| 1179 | + #ifndef V8_ENABLE_SANDBOX | ||
| 1176 | 1180 | AddOption("--secure-heap", | |
| 1177 | 1181 | "total size of the OpenSSL secure heap", | |
| 1178 | 1182 | &PerProcessOptions::secure_heap, | |
@@ -1181,6 +1185,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( | |||
| 1181 | 1185 | "minimum allocation size from the OpenSSL secure heap", | |
| 1182 | 1186 | &PerProcessOptions::secure_heap_min, | |
| 1183 | 1187 | kAllowedInEnvvar); | |
| 1188 | + #endif // V8_ENABLE_SANDBOX | ||
| 1184 | 1189 | #endif // HAVE_OPENSSL | |
| 1185 | 1190 | #if OPENSSL_VERSION_MAJOR >= 3 | |
| 1186 | 1191 | AddOption("--openssl-legacy-provider", | |
| Back | FazBrowse Home | New Git URL |
0 commit comments