From fee28ed03525fc6eac493582d72f9e410c5c2369 Mon Sep 17 00:00:00 2001 From: John Plevyak Date: Fri, 13 Sep 2019 14:45:36 -0700 Subject: [PATCH] Fix segfault by ensuring that we have created the context in the VM. (#189) * Fix segfault by ensuring that we have created the context in the VM. https://github.com/envoyproxy/envoy-wasm/issues/180 Signed-off-by: John Plevyak --- source/extensions/common/wasm/wasm.cc | 9 +++++++++ source/extensions/common/wasm/wasm.h | 1 + source/extensions/filters/http/wasm/wasm_filter.h | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/extensions/common/wasm/wasm.cc b/source/extensions/common/wasm/wasm.cc index 34c6057765e6..7bbf5094a61a 100644 --- a/source/extensions/common/wasm/wasm.cc +++ b/source/extensions/common/wasm/wasm.cc @@ -1766,6 +1766,7 @@ void Context::onCreate(uint32_t root_context_id) { Http::FilterHeadersStatus Context::onRequestHeaders() { onCreate(root_context_id_); + in_vm_context_created_ = true; // Store the stream id so that we can use it in log(). auto& stream_info = decoder_callbacks_->streamInfo(); auto& metadata = (*stream_info.dynamicMetadata() @@ -1819,6 +1820,14 @@ Http::FilterMetadataStatus Context::onRequestMetadata() { } Http::FilterHeadersStatus Context::onResponseHeaders() { + if (!in_vm_context_created_) { + // If the request is invalid then onRequestHeaders() will not be called and neither will + // onCreate() then sendLocalReply be called which will call this function. In this case we + // need to call onCreate() so that the Context inside the VM is created before the + // onResponseHeaders() call. + onCreate(root_context_id_); + in_vm_context_created_ = true; + } if (!wasm_->onResponseHeaders_) { return Http::FilterHeadersStatus::Continue; } diff --git a/source/extensions/common/wasm/wasm.h b/source/extensions/common/wasm/wasm.h index 6a27b93c6222..60afa471c08c 100644 --- a/source/extensions/common/wasm/wasm.h +++ b/source/extensions/common/wasm/wasm.h @@ -399,6 +399,7 @@ class Context : public Http::StreamFilter, Context* root_context_{nullptr}; // set in all contexts. const std::string root_id_; // set only in roots. std::string log_prefix_; + bool in_vm_context_created_ = false; bool destroyed_ = false; uint32_t next_http_call_token_ = 1; diff --git a/source/extensions/filters/http/wasm/wasm_filter.h b/source/extensions/filters/http/wasm/wasm_filter.h index 0532da328e0b..2ab2525c4d94 100644 --- a/source/extensions/filters/http/wasm/wasm_filter.h +++ b/source/extensions/filters/http/wasm/wasm_filter.h @@ -28,7 +28,7 @@ class FilterConfig : Logger::Loggable { if (!root_context_id_) { root_context_id_ = wasm.getRootContext(root_id_)->id(); } - return std::make_shared(&tls_slot_->getTyped(), root_context_id_); + return std::make_shared(&wasm, root_context_id_); } private: