Skip to content

Commit 474cba4

Browse files
committed
src: prepare for v8 sandboxing
1 parent 9eb9c26 commit 474cba4

File tree

5 files changed

+51
-4
lines changed

5 files changed

+51
-4
lines changed

src/crypto/crypto_dh.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ using ncrypto::DHPointer;
2222
using ncrypto::EVPKeyCtxPointer;
2323
using ncrypto::EVPKeyPointer;
2424
using v8::ArrayBuffer;
25+
using v8::BackingStoreInitializationMode;
2526
using v8::ConstructorBehavior;
2627
using v8::Context;
2728
using v8::DontDelete;
@@ -58,6 +59,13 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) {
5859
struct Flag {
5960
bool secure;
6061
};
62+
#if defined(V8_ENABLE_SANDBOX)
63+
auto backing = ArrayBuffer::NewBackingStore(env->isolate(), data.size(),
64+
BackingStoreInitializationMode::kUninitialized);
65+
if (data.size() > 0) {
66+
memcpy(backing->Data(), data.get(), data.size());
67+
}
68+
#else
6169
auto backing = ArrayBuffer::NewBackingStore(
6270
data.get(),
6371
data.size(),
@@ -67,6 +75,7 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) {
6775
},
6876
new Flag{data.isSecure()});
6977
data.release();
78+
#endif
7079

7180
auto ab = ArrayBuffer::New(env->isolate(), std::move(backing));
7281
return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local<Value>());

src/crypto/crypto_util.cc

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ using ncrypto::EnginePointer;
3434
using ncrypto::SSLPointer;
3535
using v8::ArrayBuffer;
3636
using v8::BackingStore;
37+
using v8::BackingStoreInitializationMode;
3738
using v8::BigInt;
3839
using v8::Context;
3940
using 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

359371
Local<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.
650662
void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
663+
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
651675
CHECK(args[0]->IsUint32());
652-
Environment* env = Environment::GetCurrent(args);
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

681705
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {

src/crypto/crypto_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class ByteSource final {
185185
// Creates a v8::BackingStore that takes over responsibility for
186186
// any allocated data. The ByteSource will be reset with size = 0
187187
// after being called.
188-
std::unique_ptr<v8::BackingStore> ReleaseToBackingStore();
188+
std::unique_ptr<v8::BackingStore> ReleaseToBackingStore(Environment* env);
189189

190190
v8::Local<v8::ArrayBuffer> ToArrayBuffer(Environment* env);
191191

src/crypto/crypto_x509.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,22 @@ MaybeLocal<Value> ToBuffer(Environment* env, BIOPointer* bio) {
131131
if (bio == nullptr || !*bio) [[unlikely]]
132132
return {};
133133
BUF_MEM* mem = *bio;
134+
#if defined(V8_ENABLE_SANDBOX)
135+
// If the v8 sandbox is enabled, then all array buffers must be allocated
136+
// via the isolate. External buffers are not allowed. So, instead of wrapping
137+
// the BIOPointer we'll copy it instead.
138+
auto backing = ArrayBuffer::NewBackingStore(env->isolate(), mem->length,
139+
BackingStoreInitializationMode::kUninitialized);
140+
memcpy(backing->Data(), mem->data, mem->length);
141+
#else
134142
auto backing = ArrayBuffer::NewBackingStore(
135143
mem->data,
136144
mem->length,
137145
[](void*, size_t, void* data) {
138146
BIOPointer free_me(static_cast<BIO*>(data));
139147
},
140148
bio->release());
149+
#endif
141150
auto ab = ArrayBuffer::New(env->isolate(), std::move(backing));
142151
Local<Value> ret;
143152
if (!Buffer::New(env, ab, 0, ab->ByteLength()).ToLocal(&ret)) return {};

src/node_options.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors,
8181
}
8282

8383
// Any value less than 2 disables use of the secure heap.
84+
#if !defined(V8_ENABLE_SANDBOX)
85+
// The secure heap is not supported when V8_ENABLE_SANDBOX is enabled.
8486
if (secure_heap >= 2) {
8587
if ((secure_heap & (secure_heap - 1)) != 0)
8688
errors->push_back("--secure-heap must be a power of 2");
@@ -93,6 +95,7 @@ void PerProcessOptions::CheckOptions(std::vector<std::string>* errors,
9395
if ((secure_heap_min & (secure_heap_min - 1)) != 0)
9496
errors->push_back("--secure-heap-min must be a power of 2");
9597
}
98+
#endif // defined(V8_ENABLE_SANDBOX)
9699
#endif // HAVE_OPENSSL
97100

98101
if (use_largepages != "off" &&
@@ -1172,6 +1175,7 @@ PerProcessOptionsParser::PerProcessOptionsParser(
11721175
"force FIPS crypto (cannot be disabled)",
11731176
&PerProcessOptions::force_fips_crypto,
11741177
kAllowedInEnvvar);
1178+
#if !defined(V8_ENABLE_SANDBOX)
11751179
AddOption("--secure-heap",
11761180
"total size of the OpenSSL secure heap",
11771181
&PerProcessOptions::secure_heap,
@@ -1180,6 +1184,7 @@ PerProcessOptionsParser::PerProcessOptionsParser(
11801184
"minimum allocation size from the OpenSSL secure heap",
11811185
&PerProcessOptions::secure_heap_min,
11821186
kAllowedInEnvvar);
1187+
#endif // !defined(V8_ENABLE_SANDBOX)
11831188
#endif // HAVE_OPENSSL
11841189
#if OPENSSL_VERSION_MAJOR >= 3
11851190
AddOption("--openssl-legacy-provider",

0 commit comments

Comments
 (0)