Skip to content

Commit 1019c2d

Browse files
xaviergonztargos
authored andcommittedJul 16, 2018
src: fix async hooks crashing when there is no node context
PR-URL: #19134 Fixes: #19104 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
1 parent 51dfebf commit 1019c2d

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed
 

‎src/env-inl.h

+3
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ inline void Environment::AssignToContext(v8::Local<v8::Context> context,
290290
const ContextInfo& info) {
291291
context->SetAlignedPointerInEmbedderData(
292292
ContextEmbedderIndex::kEnvironment, this);
293+
// Used by EnvPromiseHook to know that we are on a node context.
294+
context->SetAlignedPointerInEmbedderData(
295+
ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
293296
#if HAVE_INSPECTOR
294297
inspector_agent()->ContextCreated(context, info);
295298
#endif // HAVE_INSPECTOR

‎src/env.cc

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "node_buffer.h"
55
#include "node_platform.h"
66
#include "node_file.h"
7+
#include "node_context_data.h"
78
#include "node_worker.h"
89
#include "tracing/agent.h"
910

@@ -28,6 +29,10 @@ using v8::Symbol;
2829
using v8::Value;
2930
using worker::Worker;
3031

32+
int const Environment::kNodeContextTag = 0x6e6f64;
33+
void* Environment::kNodeContextTagPtr = const_cast<void*>(
34+
static_cast<const void*>(&Environment::kNodeContextTag));
35+
3136
IsolateData::IsolateData(Isolate* isolate,
3237
uv_loop_t* event_loop,
3338
MultiIsolatePlatform* platform,
@@ -430,7 +435,20 @@ bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) {
430435
void Environment::EnvPromiseHook(v8::PromiseHookType type,
431436
v8::Local<v8::Promise> promise,
432437
v8::Local<v8::Value> parent) {
433-
Environment* env = Environment::GetCurrent(promise->CreationContext());
438+
Local<v8::Context> context = promise->CreationContext();
439+
440+
// Grow the embedder data if necessary to make sure we are not out of bounds
441+
// when reading the magic number.
442+
context->SetAlignedPointerInEmbedderData(
443+
ContextEmbedderIndex::kContextTagBoundary, nullptr);
444+
int* magicNumberPtr = reinterpret_cast<int*>(
445+
context->GetAlignedPointerFromEmbedderData(
446+
ContextEmbedderIndex::kContextTag));
447+
if (magicNumberPtr != Environment::kNodeContextTagPtr) {
448+
return;
449+
}
450+
451+
Environment* env = Environment::GetCurrent(context);
434452
for (const PromiseHookCallback& hook : env->promise_hooks_) {
435453
hook.cb_(type, promise, parent, hook.arg_);
436454
}

‎src/env.h

+2
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ class Environment {
902902
uint64_t thread_id_ = 0;
903903
std::unordered_set<worker::Worker*> sub_worker_contexts_;
904904

905+
static void* kNodeContextTagPtr;
906+
static int const kNodeContextTag;
905907

906908
#if HAVE_INSPECTOR
907909
std::unique_ptr<inspector::Agent> inspector_agent_;

‎src/node_context_data.h

+10
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,20 @@ namespace node {
1919
#define NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX 34
2020
#endif
2121

22+
#ifndef NODE_CONTEXT_TAG
23+
#define NODE_CONTEXT_TAG 35
24+
#endif
25+
26+
#ifndef NODE_CONTEXT_TAG_BOUNDARY
27+
#define NODE_CONTEXT_TAG_BOUNDARY 36
28+
#endif
29+
2230
enum ContextEmbedderIndex {
2331
kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX,
2432
kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX,
2533
kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX,
34+
kContextTag = NODE_CONTEXT_TAG,
35+
kContextTagBoundary = NODE_CONTEXT_TAG_BOUNDARY,
2636
};
2737

2838
} // namespace node

0 commit comments

Comments
 (0)