Skip to content

Commit 830ca7d

Browse files
codebytereaduh95
authored andcommitted
src: fix null pointer call when running without a startup snapshot
Without a startup snapshot (`--no-node-snapshot`, a `--without-node-snapshot` build, or an embedder Environment that was bootstrapped from scratch) starting a Worker made a member call through a null `SnapshotData*`, and so did `NodeMainInstance` while setting itself up. It only worked because the function called does not touch `this`; UBSan reports it for every such Worker. The call existed because `IsolateData::CreateIsolateData()` took an `EmbedderSnapshotData*` and unwrapped it straight away, so the two internal callers wrapped their possibly-null `SnapshotData*` with `AsEmbedderWrapper()` only for it to be unwrapped again. Let the internal function take the `SnapshotData*` itself, unwrap in the public `CreateIsolateData()` only, and drop `AsEmbedderWrapper()`, which has no other users. Refs: #47731 Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com> PR-URL: #65820 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 9fd3e6c commit 830ca7d

7 files changed

Lines changed: 31 additions & 22 deletions

File tree

src/api/environment.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,11 @@ IsolateData* CreateIsolateData(
391391
ArrayBufferAllocator* allocator,
392392
const EmbedderSnapshotData* embedder_snapshot_data) {
393393
return IsolateData::CreateIsolateData(
394-
isolate, loop, platform, allocator, embedder_snapshot_data);
394+
isolate,
395+
loop,
396+
platform,
397+
allocator,
398+
SnapshotData::FromEmbedderWrapper(embedder_snapshot_data));
395399
}
396400

397401
void FreeIsolateData(IsolateData* isolate_data) {

src/env.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,8 @@ IsolateData* IsolateData::CreateIsolateData(
600600
uv_loop_t* loop,
601601
MultiIsolatePlatform* platform,
602602
ArrayBufferAllocator* allocator,
603-
const EmbedderSnapshotData* embedder_snapshot_data,
603+
const SnapshotData* snapshot_data,
604604
std::shared_ptr<PerIsolateOptions> options) {
605-
const SnapshotData* snapshot_data =
606-
SnapshotData::FromEmbedderWrapper(embedder_snapshot_data);
607605
if (options == nullptr) {
608606
options = per_process::cli_options->per_isolate->Clone();
609607
}

src/env.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
143143
uv_loop_t* event_loop,
144144
MultiIsolatePlatform* platform = nullptr,
145145
ArrayBufferAllocator* node_allocator = nullptr,
146-
const EmbedderSnapshotData* embedder_snapshot_data = nullptr,
146+
const SnapshotData* snapshot_data = nullptr,
147147
std::shared_ptr<PerIsolateOptions> options = nullptr);
148148
~IsolateData();
149149

@@ -662,7 +662,6 @@ struct SnapshotData {
662662
static bool FromBlob(SnapshotData* out, std::string_view in);
663663
static const SnapshotData* FromEmbedderWrapper(
664664
const EmbedderSnapshotData* data);
665-
EmbedderSnapshotData::Pointer AsEmbedderWrapper() const;
666665

667666
~SnapshotData();
668667
};

src/node_main_instance.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
5151

5252
// If the indexes are not nullptr, we are not deserializing
5353
isolate_data_.reset(
54-
CreateIsolateData(isolate_,
55-
event_loop,
56-
platform,
57-
array_buffer_allocator_.get(),
58-
snapshot_data->AsEmbedderWrapper().get()));
54+
IsolateData::CreateIsolateData(isolate_,
55+
event_loop,
56+
platform,
57+
array_buffer_allocator_.get(),
58+
snapshot_data));
5959

6060
isolate_data_->max_young_gen_size =
6161
isolate_params_->constraints.max_young_generation_size_in_bytes();

src/node_snapshotable.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -628,10 +628,6 @@ const SnapshotData* SnapshotData::FromEmbedderWrapper(
628628
return data != nullptr ? data->impl_ : nullptr;
629629
}
630630

631-
EmbedderSnapshotData::Pointer SnapshotData::AsEmbedderWrapper() const {
632-
return EmbedderSnapshotData::Pointer{new EmbedderSnapshotData(this, false)};
633-
}
634-
635631
bool SnapshotData::FromFile(SnapshotData* out, FILE* in) {
636632
return FromBlob(out, ReadFileSync(in));
637633
}

src/node_worker.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ class WorkerThreadData {
204204
isolate->SetStackLimit(w->stack_base_);
205205

206206
HandleScope handle_scope(isolate);
207-
isolate_data_.reset(IsolateData::CreateIsolateData(
208-
isolate,
209-
&loop_,
210-
w_->platform_,
211-
allocator.get(),
212-
w->snapshot_data()->AsEmbedderWrapper().get(),
213-
std::move(w_->per_isolate_opts_)));
207+
isolate_data_.reset(
208+
IsolateData::CreateIsolateData(isolate,
209+
&loop_,
210+
w_->platform_,
211+
allocator.get(),
212+
w->snapshot_data(),
213+
std::move(w_->per_isolate_opts_)));
214214
CHECK(isolate_data_);
215215
CHECK(!isolate_data_->is_building_snapshot());
216216
isolate_data_->set_worker_context(w_);

test/cctest/test_environment.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,18 @@ TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) {
355355
EXPECT_TRUE(called_cb_2);
356356
}
357357

358+
TEST_F(EnvironmentTest, WorkerInEnvironmentWithoutSnapshot) {
359+
const v8::HandleScope handle_scope(isolate_);
360+
const Argv argv;
361+
Env env{handle_scope, argv};
362+
CHECK_NULL(isolate_data_->snapshot_data());
363+
node::LoadEnvironment(*env,
364+
"const { Worker } = require('worker_threads');"
365+
"new Worker('process.exit(0)', { eval: true });")
366+
.ToLocalChecked();
367+
EXPECT_EQ(node::SpinEventLoop(*env).FromJust(), 0);
368+
}
369+
358370
TEST_F(EnvironmentTest, NoEnvironmentSanity) {
359371
const v8::HandleScope handle_scope(isolate_);
360372
v8::Local<v8::Context> context = v8::Context::New(isolate_);

0 commit comments

Comments
 (0)