diff --git a/src/env-inl.h b/src/env-inl.h index 4ef9665cbddfed..5c359c04d907cb 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -290,6 +290,9 @@ inline void Environment::AssignToContext(v8::Local context, const ContextInfo& info) { context->SetAlignedPointerInEmbedderData( ContextEmbedderIndex::kEnvironment, this); + // Used by EnvPromiseHook to know that we are on a node context. + context->SetAlignedPointerInEmbedderData( + ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr); #if HAVE_INSPECTOR inspector_agent()->ContextCreated(context, info); #endif // HAVE_INSPECTOR diff --git a/src/env.cc b/src/env.cc index 3d1a9372c93c7d..fffe5d61d0685a 100644 --- a/src/env.cc +++ b/src/env.cc @@ -4,6 +4,7 @@ #include "node_buffer.h" #include "node_platform.h" #include "node_file.h" +#include "node_context_data.h" #include "node_worker.h" #include "tracing/agent.h" @@ -28,6 +29,10 @@ using v8::Symbol; using v8::Value; using worker::Worker; +int const Environment::kNodeContextTag = 0x6e6f64; +void* Environment::kNodeContextTagPtr = const_cast( + static_cast(&Environment::kNodeContextTag)); + IsolateData::IsolateData(Isolate* isolate, uv_loop_t* event_loop, MultiIsolatePlatform* platform, @@ -430,7 +435,20 @@ bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) { void Environment::EnvPromiseHook(v8::PromiseHookType type, v8::Local promise, v8::Local parent) { - Environment* env = Environment::GetCurrent(promise->CreationContext()); + Local context = promise->CreationContext(); + + // Grow the embedder data if necessary to make sure we are not out of bounds + // when reading the magic number. + context->SetAlignedPointerInEmbedderData( + ContextEmbedderIndex::kContextTagBoundary, nullptr); + int* magicNumberPtr = reinterpret_cast( + context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kContextTag)); + if (magicNumberPtr != Environment::kNodeContextTagPtr) { + return; + } + + Environment* env = Environment::GetCurrent(context); for (const PromiseHookCallback& hook : env->promise_hooks_) { hook.cb_(type, promise, parent, hook.arg_); } diff --git a/src/env.h b/src/env.h index 9c7f4d1ba8ae3f..ede221400b4965 100644 --- a/src/env.h +++ b/src/env.h @@ -902,6 +902,8 @@ class Environment { uint64_t thread_id_ = 0; std::unordered_set sub_worker_contexts_; + static void* kNodeContextTagPtr; + static int const kNodeContextTag; #if HAVE_INSPECTOR std::unique_ptr inspector_agent_; diff --git a/src/node_context_data.h b/src/node_context_data.h index 522ce292d21684..3892b31354027d 100644 --- a/src/node_context_data.h +++ b/src/node_context_data.h @@ -19,10 +19,20 @@ namespace node { #define NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX 34 #endif +#ifndef NODE_CONTEXT_TAG +#define NODE_CONTEXT_TAG 35 +#endif + +#ifndef NODE_CONTEXT_TAG_BOUNDARY +#define NODE_CONTEXT_TAG_BOUNDARY 36 +#endif + enum ContextEmbedderIndex { kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX, kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX, kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX, + kContextTag = NODE_CONTEXT_TAG, + kContextTagBoundary = NODE_CONTEXT_TAG_BOUNDARY, }; } // namespace node