Skip to content

Commit d248ed3

Browse files
committed
env: fix use-after-free in keep-alive allocators
As per comment in the change it is possible that `Environment:AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose` is called from `node::FreeEnvironment(env)` after `node::Stop(env)` was already called. In this case platform's `per_isolate_` map won't have an entry for our isolate and the `AddIsolateFinishedCallback` will invoke the callback immediately leaving us with `keep_alive_allocators_` set to freed pointer. This commit also changes the assertion in the `AddIsolateFinishedCallback` that is triggered incorrectly.
1 parent 7d488fe commit d248ed3

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

src/env.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,17 @@ char* Environment::Reallocate(char* data, size_t old_size, size_t size) {
11531153

11541154
void Environment::AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose(
11551155
std::shared_ptr<v8::ArrayBuffer::Allocator> allocator) {
1156+
// It is possible that we can arrive here from `node::FreeEnvironment` when it
1157+
// is called after `node::Stop(env)`.
1158+
//
1159+
// In this case platform's `per_isolate_` map won't have an entry for our
1160+
// isolate and the `AddIsolateFinishedCallback` will invoke the callback
1161+
// immediately leaving us with `keep_alive_allocators_` set to freed pointer.
1162+
if (is_stopping() && started_cleanup_) {
1163+
allocator.reset();
1164+
return;
1165+
}
1166+
11561167
if (keep_alive_allocators_ == nullptr) {
11571168
MultiIsolatePlatform* platform = isolate_data()->platform();
11581169
CHECK_NOT_NULL(platform);

src/node_platform.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,10 @@ void NodePlatform::AddIsolateFinishedCallback(Isolate* isolate,
359359
Mutex::ScopedLock lock(per_isolate_mutex_);
360360
auto it = per_isolate_.find(isolate);
361361
if (it == per_isolate_.end()) {
362-
CHECK(it->second);
363362
cb(data);
364363
return;
365364
}
365+
CHECK(it->second);
366366
it->second->AddShutdownCallback(cb, data);
367367
}
368368

0 commit comments

Comments
 (0)