fix: window.open causing occasional Node.js crashes (#38754)

* fix: window.open causing occasional Node.js crashes

* chore: always free isolate data

* chore: clear pending ticks in worker thread

* fix: UAF crash when creating WebWorkerObserver

---------

Co-authored-by: deepak1556 <hop2deep@gmail.com>
This commit is contained in:
Shelley Vohr
2023-07-18 10:41:50 +02:00
committed by GitHub
parent 4ab0a5ade4
commit 8874306dc0
6 changed files with 86 additions and 41 deletions

View File

@@ -33,7 +33,6 @@
#include "shell/common/gin_helper/locker.h"
#include "shell/common/gin_helper/microtasks_scope.h"
#include "shell/common/mac/main_application_bundle.h"
#include "shell/common/node_includes.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" // nogncheck
#include "third_party/electron_node/src/debug_utils.h"
@@ -518,8 +517,9 @@ node::Environment* NodeBindings::CreateEnvironment(
args.insert(args.begin() + 1, init_script);
if (!isolate_data_)
isolate_data_ = node::CreateIsolateData(isolate, uv_loop_, platform);
auto* isolate_data = node::CreateIsolateData(isolate, uv_loop_, platform);
context->SetAlignedPointerInEmbedderData(kElectronContextEmbedderDataIndex,
static_cast<void*>(isolate_data));
node::Environment* env;
uint64_t flags = node::EnvironmentFlags::kDefaultFlags |
@@ -550,7 +550,7 @@ node::Environment* NodeBindings::CreateEnvironment(
{
v8::TryCatch try_catch(isolate);
env = node::CreateEnvironment(
isolate_data_, context, args, exec_args,
static_cast<node::IsolateData*>(isolate_data), context, args, exec_args,
static_cast<node::EnvironmentFlags::Flags>(flags));
if (try_catch.HasCaught()) {

View File

@@ -13,6 +13,9 @@
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/memory/weak_ptr.h"
#include "gin/public/context_holder.h"
#include "gin/public/gin_embedders.h"
#include "shell/common/node_includes.h"
#include "uv.h" // NOLINT(build/include_directory)
#include "v8/include/v8.h"
@@ -20,14 +23,14 @@ namespace base {
class SingleThreadTaskRunner;
}
namespace node {
class Environment;
class MultiIsolatePlatform;
class IsolateData;
} // namespace node
namespace electron {
// Choose a reasonable unique index that's higher than any Blink uses
// and thus unlikely to collide with an existing index.
static constexpr int kElectronContextEmbedderDataIndex =
static_cast<int>(gin::kPerContextDataStartIndex) +
static_cast<int>(gin::kEmbedderElectron);
// A helper class to manage uv_handle_t types, e.g. uv_async_t.
//
// As per the uv docs: "uv_close() MUST be called on each handle before
@@ -108,11 +111,24 @@ class NodeBindings {
// Notify embed thread to start polling after environment is loaded.
void StartPolling();
// Gets/sets the per isolate data.
void set_isolate_data(node::IsolateData* isolate_data) {
isolate_data_ = isolate_data;
// Clears the PerIsolateData.
void clear_isolate_data(v8::Local<v8::Context> context) {
context->SetAlignedPointerInEmbedderData(kElectronContextEmbedderDataIndex,
nullptr);
}
node::IsolateData* isolate_data(v8::Local<v8::Context> context) const {
if (context->GetNumberOfEmbedderDataFields() <=
kElectronContextEmbedderDataIndex) {
return nullptr;
}
auto* isolate_data = static_cast<node::IsolateData*>(
context->GetAlignedPointerFromEmbedderData(
kElectronContextEmbedderDataIndex));
CHECK(isolate_data);
CHECK(isolate_data->event_loop());
return isolate_data;
}
node::IsolateData* isolate_data() const { return isolate_data_; }
// Gets/sets the environment to wrap uv loop.
void set_uv_env(node::Environment* env) { uv_env_ = env; }