Skip to content

Commit

Permalink
src: fix async hooks crashing when there is no node context
Browse files Browse the repository at this point in the history
PR-URL: #19134
Fixes: #19104
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
  • Loading branch information
xaviergonz authored and targos committed Jul 16, 2018
1 parent 51dfebf commit 1019c2d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ inline void Environment::AssignToContext(v8::Local<v8::Context> 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
Expand Down
20 changes: 19 additions & 1 deletion src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -28,6 +29,10 @@ using v8::Symbol;
using v8::Value;
using worker::Worker;

int const Environment::kNodeContextTag = 0x6e6f64;
void* Environment::kNodeContextTagPtr = const_cast<void*>(
static_cast<const void*>(&Environment::kNodeContextTag));

IsolateData::IsolateData(Isolate* isolate,
uv_loop_t* event_loop,
MultiIsolatePlatform* platform,
Expand Down Expand Up @@ -430,7 +435,20 @@ bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) {
void Environment::EnvPromiseHook(v8::PromiseHookType type,
v8::Local<v8::Promise> promise,
v8::Local<v8::Value> parent) {
Environment* env = Environment::GetCurrent(promise->CreationContext());
Local<v8::Context> 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<int*>(
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_);
}
Expand Down
2 changes: 2 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,8 @@ class Environment {
uint64_t thread_id_ = 0;
std::unordered_set<worker::Worker*> sub_worker_contexts_;

static void* kNodeContextTagPtr;
static int const kNodeContextTag;

#if HAVE_INSPECTOR
std::unique_ptr<inspector::Agent> inspector_agent_;
Expand Down
10 changes: 10 additions & 0 deletions src/node_context_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1019c2d

Please sign in to comment.