From: Amos Jeffries Date: Wed, 4 May 2016 03:31:48 +0000 (+1200) Subject: Fix SIGSEGV in ESIContext response handling X-Git-Tag: SQUID_4_0_10~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f522f9b5859a9614da78b9494a47d870a2e780f0;p=thirdparty%2Fsquid.git Fix SIGSEGV in ESIContext response handling HttpReply pointer was being unlocked without heving been locked. Resulting in a double-free. Make it use RefCount instead of manual locking to ensure locked/unlock is always symmetrical. --- diff --git a/src/esi/Assign.cc b/src/esi/Assign.cc index d0cc6f91ec..47c12a6144 100644 --- a/src/esi/Assign.cc +++ b/src/esi/Assign.cc @@ -18,6 +18,7 @@ #include "esi/Assign.h" #include "esi/Context.h" #include "esi/Sequence.h" +#include "HttpReply.h" ESIAssign::~ESIAssign() { diff --git a/src/esi/Context.h b/src/esi/Context.h index 27df1ba62c..ee2f6f15ac 100644 --- a/src/esi/Context.h +++ b/src/esi/Context.h @@ -13,6 +13,7 @@ #include "err_type.h" #include "esi/Element.h" #include "esi/Parser.h" +#include "http/forward.h" #include "http/StatusCode.h" class ESIVarState; @@ -92,7 +93,7 @@ public: err_type errorpage; /* if we error what page to use */ Http::StatusCode errorstatus; /* if we error, what code to return */ char *errormessage; /* error to pass to error page */ - HttpReply *rep; /* buffered until we pass data downstream */ + HttpReplyPointer rep; /* buffered until we pass data downstream */ ESISegment::Pointer buffered; /* unprocessed data - for whatever reason */ ESISegment::Pointer incoming; /* processed data we are waiting to send, or for diff --git a/src/esi/Esi.cc b/src/esi/Esi.cc index 801cb045d6..4a960198f5 100644 --- a/src/esi/Esi.cc +++ b/src/esi/Esi.cc @@ -605,18 +605,18 @@ ESIContext::send () flags.clientwantsdata = 0; debugs(86, 5, "ESIContext::send: this=" << this << " Client no longer wants data "); /* Deal with re-entrancy */ - HttpReply *temprep = rep; + HttpReplyPointer temprep = rep; rep = NULL; /* freed downstream */ if (temprep && varState) - varState->buildVary (temprep); + varState->buildVary(temprep.getRaw()); { StoreIOBuffer tempBuffer; tempBuffer.length = len; tempBuffer.offset = pos - len; tempBuffer.data = next->readBuffer.data; - clientStreamCallback (thisNode, http, temprep, tempBuffer); + clientStreamCallback (thisNode, http, temprep.getRaw(), tempBuffer); } if (len == 0) @@ -1385,7 +1385,7 @@ ESIContext::freeResources () { debugs(86, 5, HERE << "Freeing for this=" << this); - HTTPMSGUNLOCK(rep); + rep = nullptr; // refcounted finishChildren ();