From 9b1da7c3f55c1e3ee34779b409a11dbc8488c56b Mon Sep 17 00:00:00 2001 From: John Plevyak Date: Tue, 17 Sep 2019 15:47:13 -0700 Subject: [PATCH] Fix segfault by ensuring that we have created the context in the VM. (#189) (#107) * 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 | 12 +++++++++++- source/extensions/common/wasm/wasm.h | 1 + source/extensions/filters/http/wasm/wasm_filter.h | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/extensions/common/wasm/wasm.cc b/source/extensions/common/wasm/wasm.cc index 3339f47eba58..76657a982033 100644 --- a/source/extensions/common/wasm/wasm.cc +++ b/source/extensions/common/wasm/wasm.cc @@ -1943,6 +1943,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() @@ -1992,8 +1993,17 @@ Http::FilterMetadataStatus Context::onRequestMetadata() { } Http::FilterHeadersStatus Context::onResponseHeaders() { - if (!wasm_->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; + } if (wasm_->onResponseHeaders_(this, id_) == 0) { return Http::FilterHeadersStatus::Continue; } diff --git a/source/extensions/common/wasm/wasm.h b/source/extensions/common/wasm/wasm.h index e77902270f0e..b7536a452338 100644 --- a/source/extensions/common/wasm/wasm.h +++ b/source/extensions/common/wasm/wasm.h @@ -397,6 +397,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: