From 842c5cee0e35b74703f769d6b83f07dadc278019 Mon Sep 17 00:00:00 2001 From: Sudheer Vinukonda Date: Mon, 26 Aug 2019 20:21:20 -0700 Subject: [PATCH 1/2] Add in_destroy to Http2ConnectionState to prevent double delete (similar to Http2ClientSession) Add zombie_event when destroy() is called more than once. --- proxy/http2/Http2ConnectionState.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h index 01c80cfa21c..d8d6bca3d3d 100644 --- a/proxy/http2/Http2ConnectionState.h +++ b/proxy/http2/Http2ConnectionState.h @@ -140,6 +140,11 @@ class Http2ConnectionState : public Continuation void destroy() { + if (in_destroy) { + schedule_zombie_event(); + return; + } + in_destroy = true; if (shutdown_cont_event) { shutdown_cont_event->cancel(); } @@ -374,6 +379,7 @@ class Http2ConnectionState : public Continuation Http2StreamId continued_stream_id = 0; bool _scheduled = false; bool fini_received = false; + bool in_destroy = false; int recursion = 0; Http2ShutdownState shutdown_state = HTTP2_SHUTDOWN_NONE; Http2ErrorCode shutdown_reason = Http2ErrorCode::HTTP2_ERROR_MAX; From 8884fa838ff8748da8fac90110971fe1540e6788 Mon Sep 17 00:00:00 2001 From: Sudheer Vinukonda Date: Fri, 27 Sep 2019 10:15:41 -0700 Subject: [PATCH 2/2] Make sure shutdown_cont_event isn't holding any garbage references. As it seems like there could be a race condition because the handling of HTTP2_SESSION_EVENT_SHUTDOWN_INIT is going through the event loop again and therefore may come in after the Session and its associated contexts are already cleaned up thus causing an use-after-free possibility --- proxy/http2/Http2ConnectionState.h | 1 + 1 file changed, 1 insertion(+) diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h index d8d6bca3d3d..e803d74c7df 100644 --- a/proxy/http2/Http2ConnectionState.h +++ b/proxy/http2/Http2ConnectionState.h @@ -147,6 +147,7 @@ class Http2ConnectionState : public Continuation in_destroy = true; if (shutdown_cont_event) { shutdown_cont_event->cancel(); + shutdown_cont_event = nullptr; } cleanup_streams();